我正在尝试使用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;
}
}
答案 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");
}
}