【问题标题】:how to use MEF as a Factory如何将 MEF 用作工厂
【发布时间】:2014-01-22 21:11:21
【问题描述】:

我想获得一个使用 MEF 能力的实例。

我有这个实现接口的类:

[Export(typeof(IUsersRepository))]
public class UsersRepository : DAL.IUsersRepository
{

我有一些使用这个UsersRepository 的服务(这是 WCF 项目)所以这是我尝试做的:

    #region Members
    [Import(typeof(IUsersRepository))]
    IUsersRepository UsersRepository;
    #endregion

    #region Constructors 
    public ChatService()
    {
        ICompositionService x = new CompositionContainer(new ApplicationCatalog());
        x.SatisfyImportsOnce(UsersRepository);
    }
    #endregion

但是,我得到了两个错误(第一个实际上是一个警告):

  1. UsersRepository 从未使用过
  2. UsersRepository is null

因此我在以下位置遇到异常:

x.SatisfyImportsOnce(UsersRepository);

我如何以正确的方式做到这一点? (我确实搜索了谷歌并没有找到对我有帮助的东西)

编辑:(阅读第一条回复后)

所以我设法做到了以下几点:

   #region Members
    [Import(typeof(IUsersRepository))]
    public IUsersRepository UsersRepository;
    [Import(typeof(IRoomsRepository))]
    public IRoomsRepository RoomsRepository;

    private CompositionContainer _container;
    #endregion

    #region Constructors 
    public ChatService()
    {            
        //An aggregate catalog that combines multiple catalogs
        var catalog = new AggregateCatalog();

        //Adds all the parts found in the same assembly as the Program class
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(ChatService).Assembly));

        //Create the CompositionContainer with the parts in the catalog
        _container = new CompositionContainer(catalog);

        //Fill the imports of this object
        try
        {
            this._container.ComposeParts(this);
        }
        catch (CompositionException compositionException)
        {
            Console.WriteLine(compositionException.ToString());
        }
    }
    #endregion

但我得到以下错误:

未找到与约束匹配的导出:ContractName DAL.IUsersRepository 必需的TypeIdentity DAL.IUsersRepository

虽然我确实如上所述为此接口定义了导出类。

【问题讨论】:

  • UsersRepository 可能在另一个程序集中定义 - 创建一个 DirectoryCatalog 而不是 AssemblyCatalog
  • 我解决了这个问题:catalog.Catalogs.Add(new AssemblyCatalog(Assembly.Load("DAL")));

标签: c# .net wcf mef


【解决方案1】:

为什么不按常规方式做呢?

[ImportMany]
private IEnumerable<Lazy<IPostHandler, IPostHandlerCapabilities>> _postHandlersPlugins = null;
private CompositionContainer _compositionContainer;

......
public void SomeInitFunction() 
{
    catalog.Catalogs.Add(new AssemblyCatalog(assembly));
    _compositionContainer = new CompositionContainer(catalog);

    try
    {
        _compositionContainer.ComposeParts(this);
    }
    catch (CompositionException ex)
    {
        ;
    }
}

_postHandlersPlugins 是用 Export 属性装饰的实体,请注意关于状态 - 因为您可以在共享状态下工作(默认情况下单格顿)或对于将重新创建的项目的每个请求,我正在工作懒惰,所以插件会在有人真正需要时创建。关于init - 大多数时候它是从ctor调用的。容器是搜索所有部分(具有导出属性的类)的占位符

LINK TO MSDN - MEF

当您调试它时,请查看目录并查看它是否找到零件。如果它找到您的零件并且它们不是在合成后创建的 - 可能是您没有默认 CTOR 并且它无法合成,因为它可以解析参数。如果您在目录中没有看到该零件 - 这意味着您在目录中添加了错误的组件

【讨论】:

  • 我对这个很陌生,你能补充一些解释吗?你在哪里使用 _postHandlersPlugins ?我在哪里告诉容器创建我所需类的实例?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-21
  • 1970-01-01
相关资源
最近更新 更多