如何从MEF中的基础结构库导出类?

时间:2012-08-13 23:08:08

标签: c# module export prism mef

我有一个包含两个模块的项目,一个基础架构(Common库)和Shell

enter image description here

请注意Common有一个FooService,这个ExportAttribute

[Export]
public class FooService
{
}

这个应该由Module1Module2使用,但如果我拥有ImportAttribute,它会引发错误。请注意评论。

[ModuleExport("Module1.ModuleInit", typeof(Module1.ModuleInit))]
public class ModuleInit : IModule
{
    private readonly IRegionManager _regionManager;
    public IServiceLocator _serviceLocator;

    // [Import(AllowRecomposition=true)]
    public FooService _service;

    [ImportingConstructor]
    public ModuleInit(IRegionManager regionManager, IServiceLocator serviceLocator)
    {
        _regionManager = regionManager;
        _serviceLocator = serviceLocator;
    }

    public void Initialize() { }
}

此代码与Module2相同。

  

初始化模块'Module2.ModuleInit'时发生异常。        - 异常消息是:组成保持不变。由于以下错误,更改被拒绝:   组成产生单一成分错误。根本原因是   提供如下。查看CompositionException.Errors属性   更详细的信息。

     

1)找到多个与约束匹配的导出   '((exportDefinition.ContractName ==“Common.FooService”)AndAlso   (exportDefinition.Metadata.ContainsKey(“ExportTypeIdentity”)AndAlso   “Common.FooService” .Equals(exportDefinition.Metadata.get_Item( “ExportTypeIdentity”))))”

     

导致:无法设置导入'Module1.ModuleInit._service   (ContractName =“Common.FooService”)'部分'Module1.ModuleInit'。   元素:Module1.ModuleInit._service   (ContractName =“Common.FooService”) - > Module1.ModuleInit - >   AssemblyCatalog(Assembly =“Module1,Version = 1.0.0.0,Culture = neutral,   公钥=空“)

为什么我收到此例外?我只是导出一个对象。我想知道发生了什么以及如何解决它。

请随意下载,这个项目非常小。 Download the compact project

2 个答案:

答案 0 :(得分:0)

这应该只是一个评论,但我还没有足够的代表去做。无论如何,它看起来像一个范围问题。我相信MEF v1应该自动将出口视为单身,但我认为它在v2中已被颠倒 - 不确定你使用的是哪个版本。我最近使用Microsoft.Composition(MEF for MVC)遇到了一个问题,并通过使用HTTP请求级别范围来解决它,以便在整个请求的生命周期内获得单个实例。

[System.Composition.Export(typeof(ICustomDbContext))]
[System.Composition.Shared(Boundaries.HttpRequest)]
public class CustomDbContext : ICustomDbContext { ... }

答案 1 :(得分:0)

解决方案:您将浏览除 Shell项目之外的每个项目,并查看参考资料;执行以下操作:

  • 只需删除unityextension引用,因为您使用的是MEF
  • 将“Common”引用属性“Copy local”设置为False
  • 将“Microsoft.Practices.Prism”引用属性“Copy local”设置为False
  • 将“Microsoft.Practices.Prism.MefExtensions”引用属性“Copy local”设置为False
  • 将“Microsoft.Practices.Prism.ServiceLocation”引用属性“Copy local”设置为False
  • 将“System.ComponentModel.Composition”引用属性“Copy local”设置为False

转到Bootstrapper类,添加:

protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();

            // Add this assembly to the catalog.
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));

            // Add the FooService assembly
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(FooService).Assembly));
        }

然后取消注释模块中的[Import(AllowRecomposition)]和FooService。

在运行项目之前,需要转到Visual Studio菜单,选择Build - >清洁项目。这将删除之前复制本地为真的所有dll文件。