如何将我的服务注册为全局服务或如何在我的场景中使用 MEF? [英] How to register my service as a global service or how can I use MEF in my scenario?

查看:39
本文介绍了如何将我的服务注册为全局服务或如何在我的场景中使用 MEF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建自己的具有全球知名度的服务.为了实现这一点,我遵循了这个示例解决方案.

I would like to create my own service with global visibility. To implement that, I followed this sample solution.

一切顺利,我可以在一个类中调用我的服务,这个类继承自 Package 抽象类,方式如下:

Everything goes well, I can call my service within a class, which extends from the Package abstract class, in this way:

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

因为我在一个包裹中,所以我可以轻松地调用 GetService 并且我可以获得我的服务.但是如果我想从一个不扩展 Package 抽象类的类中获取我的服务呢?

Because I'm in a Package, I can easily call GetService and I can get my service. But what about if I want to get my service from a class, which is not extends the Package abstract class?

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

For example, I have a class, which implements an ITagger interface. If I want to get a service in this class, I have to use Package.GetGlobalService() method in this way:

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

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

I tried to get my own service with the Package.GetGlobalServie(), but I always getting null. The linked sample code doesn't contain a soluiton for my problem.

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

May I missed something or I have a wrong scenario to get my service?

好的,假设我必须使用 MEF 来获取我的服务,因为我无法使用 Package.GetGlobalService() 获取我的服务.

Okay, let's say I have to use MEF to get my service, because I can't get my service with Package.GetGlobalService().

我有一个包含 2 个项目的解决方案.一个是类库,它包含这样的接口:

I have a solution with 2 projects in it. One is a class library, which contains an interface like this:

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

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

The other project is the VSPackage (has a reference with the first project), which implements my interface as well:

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

    public IEnumerable<string> GetNames()
    {
        return _names;
    }
}

假设用户单击工具"菜单下的给定菜单,逻辑会设置名称的值.直到 _names 为空.

Let's say that if the user clicks a given menu under the Tools menu, the logic set the value of the names. Until that the _names is empty.

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

I would like to use the content of this _names list at my provider, like:

[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,但每个字段都是空的,_names IEnumerable 也是.

I get the namesAccessor here, but every fields are null, the _names IEnumerable also.

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

Is there a way to force the MEF to import my accessor again when the user click to the menu button? What did I wrong?

感谢您的回答!:)

推荐答案

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

You should use MEF to composes services for your extensions; not the old COM-based ServiceProvider stuff.

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

Put all of your actual code in MEF-exported classes, then invoke them from the package class using the SComponentModel service.

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

For more information, see my blog.

这篇关于如何将我的服务注册为全局服务或如何在我的场景中使用 MEF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆