如何使用MEF作为工厂

时间:2014-01-22 21:11:21

标签: c# .net wcf mef

我想获得一个使用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
  3. 因此我得到一个例外:

    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 RequiredTypeIdentity DAL.IUsersRepository

    虽然我确实为这个界面定义了导出类,如上所述。

1 个答案:

答案 0 :(得分: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属性修饰的实体,请注意有关状态 - 因为您可以在共享状态下工作(singelton - 默认情况下)或者对于项目的每个请求都将重新创建,我正在工作懒惰所以插件将在某些人真正需要时创建。关于init - 大部分时间是从ctor调用的。容器是占位符,用于搜索所有部分(具有导出属性的类)

LINK TO MSDN - MEF

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