简体   繁体   中英

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:

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

My HandlerUser class is:

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:

        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. 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. 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:

    [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.

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. When you do this, you will be exporting by the property name "Handler" and not the typeof(Handler) like you do in Class definition. 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.

More information on exporting using MEF can be found here

The reason you see only one export is because the CompositionContainer doesn't know about the other two objects you created yourself.

To let the CompositionContainer use the two other Handlers , pass each HandleUser to the CompositionContainer.ComposeParts method. 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> ). 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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