MEF导出属性
本文关键字:属性 MEF | 更新日期: 2023-09-27 18:14:15
我试图在我定义的类中获得导出的属性,但我认为缺少一些我不知道的东西。下面是我的Handler类:
public class Handler
{
public string Message { get; private set; }
public void Create(string msg)
{
Message = msg;
}
}
我的HandlerUser类是:
public class HandlerUser
{
[Export(typeof(Handler))]
public Handler MyHandler { get; set; }
public string Name { get; set; }
public HandlerUser() { MyHandler = new Handler(); }
}
在我的program。cs中我有:
var catalogs = new AggregateCatalog();
var catalog = new ApplicationCatalog();
catalogs.Catalogs.Add(catalog);
CompositionContainer pluginsCompositionContainer = new CompositionContainer(catalogs);
HandlerUser u1 = new HandlerUser();
u1.MyHandler.Create("U1");
HandlerUser u2 = new HandlerUser();
u2.MyHandler.Create("U2");
var exports = pluginsCompositionContainer.GetExports<Handler>();
Console.Write(exports.Count());
我希望看到2个出口,他们应该有"U1","U2"作为他们的消息,但我只看到一个,消息为空。我不知道缺少了什么,我只是想导出每个用代码制作的Handler
,并且能够做一些逻辑。任何帮助都太好了。
当使用MEF时,您不能导出某些类的属性或方法(作为类型),您需要导出类本身,因此您的代码应该像这样:
[Export(typeof(Handler))]
public class HandlerUser : Handler
{
public string Name { get; set; }
public HandlerUser() : base()
{
}
}
但是由于你正在使用MEF,这意味着你正在尝试为你的应用程序添加可扩展性,考虑到这一点,我会使"Handle"成为一个接口而不是一个类,所以这样任何人都可以实现他们想要的方式,他们只需要实现接口。
在这种情况下,就像:
public interface IHandler
{
string Message { get; }
public void Create(string msg);
}
[Export(typeof(Handler))]
public class HandlerUser : IHandler
{
public string Name { get; set; }
public string Message { get; private set;}
public HandlerUser()
{
}
public void Create(string msg)
{
this.Message = msg
}
}
编辑:我已经更新了答案,以清楚地了解MEF如何与导出一起工作,您实际上可以导出属性,但不是在问题的上下文中。当您这样做时,您将通过属性名称"Handler"导出,而不是像在类定义中那样使用typeof(Handler)。属性和方法导出是一个很酷的功能,但是有一些限制(方法导出的最大参数数是4!),在可能的情况下首选类导出。
关于使用MEF导出的更多信息可以在这里找到
您只看到一个导出的原因是因为CompositionContainer
不知道您自己创建的其他两个对象。
让CompositionContainer使用另外两个Handlers
,将每个HandleUser传递给CompositionContainer。ComposeParts方法。这个将把处理程序注册到容器。
pluginsCompositionContainer.ComposeParts(u1);
pluginsCompositionContainer.ComposeParts(u2);
然后,当您获得导出时,您将注意到它们不是两个(如您最初期望的那样),而是三个。这两个是您自己创建并使用CompositionContainer.ComposeParts
注册到容器的,另外一个是容器自动创建的(实际上是Lazy<Handler>
)。最后一个是您在示例代码中看到的。当您尝试访问这个特定的导出值时,容器将创建HandlerUser
的实例,然后返回对Handler
的引用。