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

Oma*_*mar 10 dependency-injection mef ninject

我的应用程序使用MEF从外部程序集导出一些类.这些类是为构造函数注入而设置的.我面临的问题是,当我尝试访问它们时,MEF正在尝试实例化类.有没有办法让Ninject负责该类的实例化?

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;
Run Code Online (Sandbox Code Playgroud)

更新:

有多个类实现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;
     }


}
Run Code Online (Sandbox Code Playgroud)

使用MEF,我想获得任何MyClassOneMyClassTwo再有Ninject提供的实例MyRepositoryYourRepository(注意,这两个是一个Ninject模块必将在主部件,而不是他们在组装)

Rub*_*ink 6

您可以使用Ninject Load机制将导出的类放入混合中,然后您可以:

kernel.GetAll<IMyInterface>()
Run Code Online (Sandbox Code Playgroud)

创建是懒惰的(即每个impl IMyInterface都是在迭代上面创建的)IIRC,但是看看源代码中的测试(非常干净和可读,你没有任何借口:P)确定.

如果您不需要懒惰,请使用LINQ ToArrayToList获取IMyInterface[]List<IMyInterface>

或者您可以使用低级别Resolve()的方法系列(再次,查看样本的测试)来获得符合条件的服务[如果您想要进行一些过滤或除了使用实例之外的其他东西 - 尽管绑定元数据可能是那里的解决方案]

最后,如果您可以在解释中编辑您是否需要懒惰本身,或者是为了说明一点.(并且在Lazy<T>这里和一般情况下搜索Ninject和autofac的某些样本 - 如果在源代码中有任何示例,请回想一下 - 不要认为它仍然在3.5上)

编辑:在这种情况下,你想要一个具有以下内容的绑定:

Bind<X>().To<>().In...().Named( "x" );
Run Code Online (Sandbox Code Playgroud)

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

然后,当您在父程序集中进行解析时,使用Kernel.Get<>带有name参数的重载来指示您想要的那个(不需要懒惰,数组或IEnumerable).该Named机制是Ninject中绑定元数据概念的一个特定的(只有一个或两个辅助扩展实现它的通用概念) - 如果超出简单名称的某些东西不足,则有足够的空间来定制它.

如果您使用MEF构造对象,则可以使用该Kernel.Inject()机制来注入属性.问题是,无论是MEF或Ninject -已找到类型(Ninject:通常通过Bind()ModuleS或通过扫描扩展,之后可以做一个Resolve实例之前,子集绑定-虽然这你通常做的心不是东西) -已实例化类型(Ninject:通常通过a Kernel.Get(),但如果你通过例如MEF发现类型,你可能会使用Kernel.Get(Type)重载) - 必须注入类型(Ninject:通常通过a Kernel.Inject(),或隐含在`Kernel.Get())

我还不清楚为什么你觉得你需要混合和破坏两者 - 最终在构造和构造函数注入期间共享任务不是lib的核心用例,即使它们都是非常可组合的库.您是否有约束力,或者您是否对双方都有重大利益?