据我了解,为了使导入/导出属性彼此正确连接,我必须为每个具有这些属性的新实例调用compositionContainerInstance.Compose(...)
。
是否有可能自动发生这种情况,所以每当我创建一些可组合类的新实例时,我都不必这样做?
这将是一个例子,尽管它很长,它抽象了我的问题。
public class Worker1
{
[Import(typeof(IDataProvider))]
public IDataProvider DataProvider;
public Worker2 second;
//use data provider to perform logic
}
public class Worker2
{
[Import(typeof(IDataProvider))]
public IDataProvider DataProvider;
//use data provider to perform logic
}
[Export(typeof(IDataProvider))]
public class GeoDataProvider : IDataProvider
{
//implements logic
}
public class Container
{
private Worker1 t1;
public void Init()
{
AggregateCatalog cat = new AggregateCatalog();
cat.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
cat.Catalogs.Add(new DirectoryCatalog("."));
CompositionContainer c = new CompositionContainer(cat);
c.ComposeParts(new GeoDataProvider(), this);
}
public void PerformLogic()
{
t1 = new Worker1;
//here it fails because I need c.ComposeParts(t1):
t1.DoSomethingWithProvider();
//but even if I do c.ComposeParts(t1), still the t1.second.DataProvider will be null
//how to avoid this?
}
}
我希望能够自由创建Worker1 / Worker2的新实例,而无需知道必须在使用前编写它们。那可行吗?
答案 0 :(得分:4)
有人必须知道他们需要写作。
如果您要自由创建Worker1和Work2实例而不是让MEF创建它们,那么您还必须让MEF有机会满足新实例的导入,或者如您所发现的那样,IDataProvider字段永远不会被填充进行。
这是一个让MEF根据需要创建类的示例。只需要一次“ComposeParts”调用即可完成所有设置。
[Export]
public class Worker1
{
[Import]
public IDataProvider DataProvider;
[Import]
public Worker2 second;
//use data provider to perform logic
public void DoSomethingWithProvider() {
}
}
[Export]
public class Worker2
{
[Import]
public IDataProvider DataProvider;
//use data provider to perform logic
}
[Export( typeof( IDataProvider ) )]
public class GeoDataProvider : IDataProvider
{
//implements logic
}
public class Container
{
[Import]
private Worker1 t1;
public void Init()
{
AggregateCatalog cat = new AggregateCatalog();
cat.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );
cat.Catalogs.Add( new DirectoryCatalog( "." ) );
CompositionContainer c = new CompositionContainer( cat );
c.ComposeParts( this );
}
public void PerformLogic()
{
t1.DoSomethingWithProvider();
}
}