Factory pattern with Managed Ext Framework (MEF)

大兔子大兔子 提交于 2019-12-02 01:49:19

问题


I am trying to implement Factory Pattern with MEF.

Here is my solution

Core Project

IClass
ObjectFactory static Class(This is where the problem is)

Project A

[Export(typeof(IClass))]
[ExportMetadata("Type", "TypeA")]
public classA : IClass
{}

ProjectB

[Export(typeof(IClass))]
[ExportMetadata("Type", "TypeB")]
public classB : IClass
{}

I am facing problem when I am trying to create object dynamically

And here is factory class:

public static class ObjectFactory
{
    private static readonly CompositionContainer _container;

    [ImportMany]
    public static IEnumerable<Lazy<IClass, IMetaData>> objectTypes;
    static ObjectFactory()
    {
        AggregateCatalog catalog = new AggregateCatalog();

        catalog.Catalogs.Add(new DirectoryCatalog(Environment.CurrentDirectory));
        _container = new CompositionContainer(catalog);

        try
        {
            objectTypes = _container.GetExports<IClass, IMetaData>();
        }
        catch (CompositionException compositionException)
        {
            Console.WriteLine(compositionException.ToString());
            Console.ReadLine();
        }
    }

    public static IClass CreateObject(ObectType objectType)
    {
        IClass outProvider;

        Type typeToLoad = objectTypes.Where(x => x.Metadata.Type == objectType.ToString()).FirstOrDefault().GetType();
        outProvider = (IClass)Activator.CreateInstance(typeToLoad);

        return outProvider;
    }
}

回答1:


If you want a new "NonShared" instance provided on every call to CreateObject then I suggest this refactoring.

private static readonly CompositionContainer _container;

static ObjectFactory()
{       
    var directoryCatalog = new DirectoryCatalog(Environment.CurrentDirectory)
    _container = new CompositionContainer(directoryCatalog);        
}

public static IClass CreateObject(ObectType objectType)
{       
    var objectTypes objectTypes = new List<Lazy<IClass, IMetaData>>();
    try
    {
       objectTypes.AddRange(_container.GetExports<IClass, IMetaData>());
    }
    catch (CompositionException compositionException)
    {
        Console.WriteLine(compositionException.ToString());
        Console.ReadLine();
    }

    return objectTypes.FirstOrDefault(x => x.Metadata.Type == objectType.ToString());
}

You see MEF will resolve new instances (non shared ones that is) every time it composes types or you you call GetExports (and all other overload of this function). Alternatively you can export IClass factories instead, then you will have a collection of there providers.

P.S. [ImportMany] on objectTypes member in your example is superfluous, since you are not composing this type (I don't believe you even can since its static), you are simply setting it programmatically from the output of GetExports




回答2:


I could fix the issue

public static IClass CreateObject(ObectType objectType)
    {
        return objectTypes.Where(x => x.Metadata.Type == objectType.ToString()).FirstOrDefault().Value;
    }



回答3:


You can try below solution

//Project A

[PartCreationPolicy(CreationPolicy.NonShared)]
[Export("TypeA", typeof(IClass))]
public classA : IClass
{}

//Project B

 [PartCreationPolicy(CreationPolicy.NonShared)]
    [Export("TypeB", typeof(IClass))]
    public classB : IClass
    {}

// Your class with new Create Object Method using generics

 public static class ObjectFactory
    {
        private static readonly CompositionContainer _container;

        [ImportMany]
        public static IEnumerable<Lazy<IClass, IMetaData>> objectTypes;
        static ObjectFactory()
        {
            AggregateCatalog catalog = new AggregateCatalog();

            catalog.Catalogs.Add(new DirectoryCatalog(Environment.CurrentDirectory));
            _container = new CompositionContainer(catalog);

        }
    //get object method
        public static T CreateObject<T>(string objectType)
        {
            try
                {
                    return _container?.GetExportedValueOrDefault<T>(objectType);
                }
                catch (Exception)
                {
                }
                return null;
        }
    }

// Class To create Objects

public class classToConsume 
        {
          public void CreateMEFInstances()
           {


              IClass objClassA = ObjectFactory.CreateObject<IClass>("TypeA");
               IClass objClassB = ObjectFactory.CreateObject<IClass>("TypeB");
            }
        }


来源:https://stackoverflow.com/questions/26292563/factory-pattern-with-managed-ext-framework-mef

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!