带有托管扩展框架(MEF)的工厂模式
本文关键字:MEF 工厂 模式 框架 扩展 | 更新日期: 2023-09-27 18:26:10
我正在尝试用MEF实现工厂模式。
这是我的解决方案
核心项目
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;
}
}
如果您希望在每次调用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工厂,然后你会有一个供应商的集合。
在您的示例中,objectTypes成员上的p.S.[ImportMany]是多余的,因为您没有编写此类型(我认为您甚至不能编写,因为它是静态的),您只是从GetExports 的输出中以编程方式设置它
我可以修复问题
public static IClass CreateObject(ObectType objectType)
{
return objectTypes.Where(x => x.Metadata.Type == objectType.ToString()).FirstOrDefault().Value;
}
您可以尝试以下解决方案
//项目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");
}
}