繁体   English   中英

C#:MEF导出属性

[英]C#: MEF Exporting Properties

我正在尝试在定义的类中获取导出的属性,但是我认为缺少一些我不知道的东西。 这是我的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”成为一个Interface而不是一个Class,因此任何人都可以通过这种方式实现他们想要的方式,他们只需要实现接口。

在这种情况下,将是:

    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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM