C# 两次导入类型会导致MEF失败
我试图用MEF编写一个小模块系统,因此我有一个基本模块,如下所示:C# 两次导入类型会导致MEF失败,c#,mef,C#,Mef,我试图用MEF编写一个小模块系统,因此我有一个基本模块,如下所示: public abstract class Module : IModule { [Import] private IShell _shell; protected IShell Shell { get { return _shell; } } } 还有一些类似的模块: [Export(typeof(IModule))] public class TodoListMod
public abstract class Module : IModule
{
[Import]
private IShell _shell;
protected IShell Shell
{
get { return _shell; }
}
}
还有一些类似的模块:
[Export(typeof(IModule))]
public class TodoListModule : Module
{
}
如您所见,基本模块依赖于IShell。我有一个这样的实现:
[Export(typeof(IShell))]
public class ShellViewModel : IShell
{
[ImportMany]
private IEnumerable<IModule> _modules;
.... and later...
private void InitializeModules()
{
foreach (var module in _modules)
{
// init modules.
}
}
}
因此,原因是我们有两个实现通过基类获得IShell。为什么会这样
这是我的容器配置:
// Add all assemblies to AssemblySource (using a temporary DirectoryCatalog).
var directoryCatalog = new DirectoryCatalog(@"./");
AssemblySource.Instance.AddRange(
directoryCatalog.Parts
.Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly)
.Where(assembly => !AssemblySource.Instance.Contains(assembly)));
// Prioritise the executable assembly. This allows the client project to override exports, including IShell.
// The client project can override SelectAssemblies to choose which assemblies are prioritised.
var priorityAssemblies = SelectAssemblies().ToList();
var priorityCatalog = new AggregateCatalog(priorityAssemblies.Select(x => new AssemblyCatalog(x)));
var priorityProvider = new CatalogExportProvider(priorityCatalog);
// Now get all other assemblies (excluding the priority assemblies).
var mainCatalog = new AggregateCatalog(
AssemblySource.Instance
.Where(assembly => !priorityAssemblies.Contains(assembly))
.Select(x => new AssemblyCatalog(x)));
var mainProvider = new CatalogExportProvider(mainCatalog);
container = new CompositionContainer(priorityProvider, mainProvider);
priorityProvider.SourceProvider = container;
mainProvider.SourceProvider = container;
var batch = new CompositionBatch();
BindServices(batch);
batch.AddExportedValue(mainCatalog);
container.Compose(batch);
当任何其他类导入IShell时也会发生这种情况为什么需要编写?当您处理尝试引用模块的未知对象时,此功能非常好。也许这能帮你。在这里,我描述了批量导入是如何工作的,您可以下载一个能够编写的工作解决方案,IShell是否可能从IModule中导入?如果是这样的话,您可能会在尝试撰写时陷入循环依赖,因为ShellViewModel@JPVensonIShell不继承IModule。配置代码是我为Caliburn.Micro找到的一些引导代码的一部分。我已经有了一个可行的解决方案,但我无法找出有什么不同的做法,因为配置代码就在那里。
// Add all assemblies to AssemblySource (using a temporary DirectoryCatalog).
var directoryCatalog = new DirectoryCatalog(@"./");
AssemblySource.Instance.AddRange(
directoryCatalog.Parts
.Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly)
.Where(assembly => !AssemblySource.Instance.Contains(assembly)));
// Prioritise the executable assembly. This allows the client project to override exports, including IShell.
// The client project can override SelectAssemblies to choose which assemblies are prioritised.
var priorityAssemblies = SelectAssemblies().ToList();
var priorityCatalog = new AggregateCatalog(priorityAssemblies.Select(x => new AssemblyCatalog(x)));
var priorityProvider = new CatalogExportProvider(priorityCatalog);
// Now get all other assemblies (excluding the priority assemblies).
var mainCatalog = new AggregateCatalog(
AssemblySource.Instance
.Where(assembly => !priorityAssemblies.Contains(assembly))
.Select(x => new AssemblyCatalog(x)));
var mainProvider = new CatalogExportProvider(mainCatalog);
container = new CompositionContainer(priorityProvider, mainProvider);
priorityProvider.SourceProvider = container;
mainProvider.SourceProvider = container;
var batch = new CompositionBatch();
BindServices(batch);
batch.AddExportedValue(mainCatalog);
container.Compose(batch);