带有Managed Ext Framework(MEF)的工厂模式

时间:2014-10-10 05:33:40

标签: c# mef factory-pattern

我正在尝试使用MEF实现Factory Pattern。

这是我的解决方案

核心项目

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

项目A

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

项目B

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

我在尝试动态创建对象时遇到问题

这是工厂类:

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

3 个答案:

答案 0 :(得分:2)

如果你想在每次调用CreateObject时提供一个新的“NonShared”实例,那么我建议你进行这种重构。

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());
}

您会看到MEF每次组合类型时都会解析新实例(非共享实例),或者您调用GetExports(以及此函数的所有其他重载)。或者,您可以导出IClass工厂,然后您将拥有一些供应商。

P.S。你的例子中的objectTypes成员的[ImportMany]是多余的,因为你没有组成这种类型(我甚至不相信你的静态),你只需从GetExports的输出中以编程方式设置它

答案 1 :(得分:0)

我可以解决问题

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

答案 2 :(得分:0)

您可以尝试以下解决方案

// 项目A

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

// 项目B

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

//您的类具有使用泛型的新创建对象方法

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

//创建对象的类

public class classToConsume 
        {
          public void CreateMEFInstances()
           {


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