如何将我的服务注册为全球服务,或者在我的场景中如何使用MEF

本文关键字:我的 服务 MEF 或者 何使用 注册 | 更新日期: 2023-09-27 18:00:55

我想创建自己的具有全局可见性的服务。为了实现这一点,我遵循了这个示例解决方案。

一切都很顺利,我可以在一个类中调用我的服务,该类从Package抽象类扩展而来,如下所示:

public class ClientPackage : Package
{
   private void GetGlobalServiceCallback(object sender, EventArgs args)
   {
      IMyGlobalService service = GetService(typeof(SMyGlobalService)) as IMyGlobalService;
   }
}

因为我在一个包中,我可以很容易地调用GetService,我可以获得我的服务。但是,如果我想从一个类中获得服务,而不是扩展Package抽象类,该怎么办?

例如,我有一个类,它实现了一个ITagger接口。如果我想在这个类中获得服务,我必须以这种方式使用Package.GetGlobalService((方法:

var txtMgr = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager));

我试着用Package.GetGlobalServie((获得自己的服务,但总是为null。链接的示例代码不包含解决我的问题的解决方案。

我可能错过了什么,或者我有一个错误的场景来获得服务?

编辑:

好吧,假设我必须使用MEF才能获得服务,因为我无法使用Package.GetGlobalService((.获得服务

我有一个解决方案,里面有两个项目。一个是类库,它包含这样一个接口:

public interface INamesAccessor
{
    IEnumerable<string> GetNames();
}

另一个项目是VSPackage(参考了第一个项目(,它也实现了我的接口:

[Export(typeof(INamesAccessor))]
public sealed class BitbucketExtensionPackage : Package, INamesAccessor
{
    private IEnumerable<string> _names { get; set; }
    public IEnumerable<string> GetNames()
    {
        return _names;
    }
}

假设用户单击"工具"菜单下的给定菜单,则逻辑设置名称的值。在此之前,_names为空。

我想在我的提供商处使用此名称列表的内容,如:

[Export(typeof(ITaggerProvider))]
[ContentType("text")]
[TagType(typeof(CommentTag))]
internal sealed class CommentTaggerProvider : ITaggerProvider
{
    [Import]
    public INamesAccessor _namesAccessor { get; set; }
    public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
    {
        if (buffer == null)
            throw new ArgumentNullException("buffer");
        return buffer.Properties.GetOrCreateSingletonProperty(() => new CommentTagger(buffer, _namesAccessor )) as ITagger<T>;
    }
}

我在这里得到了namesAccessor,但每个字段都是null,_names IEnumerable也是。

当用户单击菜单按钮时,有没有办法强制MEF再次导入我的访问者?我做错了什么?

谢谢你的回答!:(

如何将我的服务注册为全球服务,或者在我的场景中如何使用MEF

您应该使用MEF为您的扩展组合服务;而不是旧的基于COM的ServiceProvider的东西。

将所有实际代码放入MEF导出的类中,然后使用SComponentModel服务从包类中调用它们。

有关更多信息,请参阅我的博客。