代码之家  ›  专栏  ›  技术社区  ›  Omar

如何使用Ninject实例化MEF导出的对象?

  •  10
  • Omar  · 技术社区  · 14 年前

    我的应用程序使用MEF从外部程序集中导出一些类。这些类是为构造函数注入而设置的。我面临的问题是

    IEnumerable<Lazy<IMyInterface>> controllers = 
        mefContainer.GetExports<IMyInterface>();
    
    // The following line throws an error because MEF is 
    // trying to instantiate a class that requires 5 parameters
    IMyInterface firstClass = controllers.First().Value;
    

    有多个类可以实现 IMyInterface 我想选择一个具有特定名称的,然后让Ninject创建一个实例。我不确定我是否想要懒惰。

    [Export(typeof(IMyInterface))]
    public class MyClassOne : IMyInterface {
    
         private MyRepository one;
         private YourRepository two;
    
         public MyClassTwo(MyRepository repoOne, YourRepository repoTwo) {
                one = repoOne;
                two = repoTwo;
         }         
    }
    
    [Export(typeof(IMyInterface))]
    public class MyClassTwo : IMyInterface {
    
         private MyRepository one;
         private YourRepository two;
    
         public MyClassTwo(MyRepository repoOne, YourRepository repoTwo) {
                one = repoOne;
                two = repoTwo;
         }
    
    
    }
    

    使用MEF,我想 MyClassOne MyClassTwo 然后让Ninject提供 MyRepository YourRepository (注意,这两个绑定在主程序集中的Ninject模块中,而不是它们所在的程序集中)

    2 回复  |  直到 14 年前
        1
  •  6
  •   Community Egal    7 年前

    你可以用这个 Ninject Load mechanism

    kernel.GetAll<IMyInterface>()
    

    创建是懒惰的(即 IMyInterface source (这是非常干净和可读性,你没有借口:P)是肯定的。

    如果你不需要懒惰,就用林克的 ToArray ToList 得到一个 IMyInterface[] List<IMyInterface>

    或者你可以用低级的 Resolve()

    最后,如果你可以编辑一个关于你是否需要懒惰本身的解释,或者你这样做是为了说明一个观点。(并搜索 Lazy<T>

    编辑:在这种情况下,您希望绑定具有:

    Bind<X>().To<>().In...().Named( "x" );
    

    在子程序集中的模块注册中。

    Kernel.Get<> 超负荷,需要 name 参数来指示所需的参数(不需要惰性、数组或 IEnumerable ). 这个 Named

    如果您使用MEF来构造对象,那么可以使用 Kernel.Inject() mechanism 注入属性。问题是不是MEF或者Ninject Bind() 在里面 Module Resolve 在实例化之前对绑定进行子集化(尽管这不是通常要做的事情) -必须实例化类型(Ninject:通常通过 Kernel.Get() Kernel.Get(Type) overloads ) 内核。注入() ,或隐含在`内核。获取())

    我还不清楚的是,为什么您觉得需要将这两个库混为一谈——最终在构建和构造函数注入期间共享职责并不是这两个库的核心用例,即使它们都是非常可组合的库。你有约束条件,还是双方都有关键利益?

        2
  •  0
  •   silverfighter    14 年前

    请参阅以下文档:

    http://mef.codeplex.com/wikipage?title=PartCreator

    你的情况会完全不同 我还将使用元数据和自定义属性

    [ImportMany(AllowRecomposition=true)] 
        IEnumerable<ExportFactory<IMyInterFace, IMyInterfaceMetaData>> Controllers{ get; set; } 
    
    public IMyInterface CreateControllerFor(string parameter)
    {
    var controller = Controllers.Where(v => v.Metadata.ControllerName == parameter).FirstOrDefault().CreateExport().Value; 
                return controller; 
    }
    

    或使用 return Controllers.First() 没有元数据

    然后你就可以在那附近编码ninject部分,甚至使用MEF