如何将我的服务注册为全局服务或如何在我的场景中使用 MEF? [英] How to register my service as a global service or how can I use MEF in my scenario?
问题描述
我想创建自己的具有全球知名度的服务.为了实现这一点,我遵循了这个示例解决方案.
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屋!