简体   繁体   English

C#:MEF导出属性

[英]C#: MEF Exporting Properties

I am trying to get the Exported Properties in my defined classes, but I think something is missing that I don't know of. 我正在尝试在定义的类中获取导出的属性,但是我认为缺少一些我不知道的东西。 Here is my Handler class: 这是我的Handler类:

public class Handler
{
    public string Message { get; private set; }
    public void Create(string msg)
    {
        Message = msg;
    }
}

My HandlerUser class is: 我的HandlerUser类是:

public class HandlerUser
{
    [Export(typeof(Handler))]
    public Handler MyHandler { get; set; }
    public string Name { get; set; }

    public HandlerUser() { MyHandler = new Handler(); }
}

And in my program.cs I have: 在我的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());

I expect to see 2 exports, and They should have "U1","U2" as their message, But I only see one, and the message is null. 我希望看到2个导出,并且它们的消息中应该包含“ U1”,“ U2”,但是我只看到一个,消息为空。 I can't figure out what's missing, I simple want to have an export of Every Handler made in code, and just be able to do some logic. 我无法弄清缺少的内容,我只是想导出用代码制作的每个Handler程序,并且能够执行一些逻辑。 Any help would be great. 任何帮助都会很棒。

When using MEF, you cannot export properties or methods (as types) of some class, you need to export the class itself, so your code should be like this: 使用MEF时,无法导出某个类的属性或方法(作为类型),需要导出类本身,因此代码应如下所示:

    [Export(typeof(Handler))]
    public class HandlerUser : Handler
    {
        public string Name { get; set; }

        public HandlerUser() : base()
        {
        }
    }

But since you are using MEF, this means that you are trying to add extensibility to you application, considering this, i would make "Handle" an Interface and not a class, so this way anyone can implement the way they want, they just need to implement the interface. 但是,由于您使用的是MEF,这意味着您正在尝试为应用程序添加可扩展性,考虑到这一点,我将使“ Handle”成为一个Interface而不是一个Class,因此任何人都可以通过这种方式实现他们想要的方式,他们只需要实现接口。

In this case, would be like: 在这种情况下,将是:

    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
        }
    }

Edit: 编辑:

I have updated the answer to be clear about how MEF works with exports, you can in fact export a property, but not in the context of the question. 我已经更新了答案,以明确MEF如何与导出配合使用,实际上您可以导出属性,但不能在问题范围内进行。 When you do this, you will be exporting by the property name "Handler" and not the typeof(Handler) like you do in Class definition. 执行此操作时,将使用属性名称“ Handler”而不是像在类定义中一样的typeof(Handler)进行导出。 Property and method exports are a cool feature, but there are some limitations (the max number of parameters of a method export is 4!), prefer Class Exports where possible. 属性和方法导出是一个很酷的功能,但是有一些限制(方法导出的最大参数数量为4!),请尽可能使用类导出。

More information on exporting using MEF can be found here 有关使用MEF导出的更多信息,请参见此处

The reason you see only one export is because the CompositionContainer doesn't know about the other two objects you created yourself. 您仅看到一个导出的原因是因为CompositionContainer不了解您自己创建的其他两个对象。

To let the CompositionContainer use the two other Handlers , pass each HandleUser to the CompositionContainer.ComposeParts method. 若要让CompositionContainer使用其他两个Handlers ,请将每个HandleUser传递给CompositionContainer.ComposeParts方法。 This one will register the handlers to the container. 这将把处理程序注册到容器中。

pluginsCompositionContainer.ComposeParts(u1);
pluginsCompositionContainer.ComposeParts(u2);

Then when you get the exports you will notice that they are not two (as you initially expected), but three. 然后,当您获得出口时,您会注意到它们不是两个(如您最初预期的那样),而是三个。 The two that you created yourself and registered to the container using CompositionContainer.ComposeParts plus the one that the container has created automatically (actually it's a Lazy<Handler> ). 您自己创建的两个对象是使用CompositionContainer.ComposeParts注册到容器的,再加上容器已自动创建的两个对象(实际上是Lazy<Handler> )。 This last one is the one you see in your sample code. 最后一个是您在示例代码中看到的。 When you will try to access this specific exported value, the container will create an instance of HandlerUser and then return the reference to the Handler . 当您尝试访问此特定的导出值时,容器将创建HandlerUser的实例,然后将引用返回给Handler

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

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