我的应用程序使用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;
有多个类实现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模块,而不是它们所在的组件)
答案 0 :(得分:6)
您可以使用Ninject Load
mechanism将导出的类添加到组合中,然后您:
kernel.GetAll<IMyInterface>()
创建是懒惰的(即,在迭代上面的IIRC时动态创建IMyInterface
的每个impl),但是看看source中的测试(非常清洁和可读,你没有任何借口:P)确定。
如果您不需要懒惰,请使用LINQ的ToArray
或ToList
获取IMyInterface[]
或List<IMyInterface>
或者您可以使用低级别Resolve()
系列方法(再次查看样本测试)以获得符合条件的服务[如果您想要进行一些过滤或其他方法,而不仅仅是使用一个实例 - 虽然绑定元数据可能是那里的解决方案]
最后,如果你可以在一个解释中编辑你是否需要懒惰本身,或者是为了说明一点。 (并在这里搜索Lazy<T>
,一般来说,对于某些样本,无论是Ninject还是autofac,都无法回忆 - 如果源代码中有任何示例 - 请不要认为它仍然在3.5上。
编辑:在这种情况下,您需要一个具有以下内容的绑定:
Bind<X>().To<>().In...().Named( "x" );
在子程序集的模块中注册。
然后当您在父程序集中解析时,使用Kernel.Get<>
重载,该重载采用name
参数来指示您想要的那个(不需要懒惰,数组或{{1} })。 IEnumerable
机制是Ninject中绑定元数据概念的一个特定(只有一个或两个辅助扩展实现它的通用概念) - 如果超出简单名称的某些东西不够,那么有足够的空间来定制它。
如果您使用MEF构建对象,则可以使用Kernel.Inject()
mechanism来注入属性。问题是MEF或Ninject
- 必须找到类型(Ninject:通常在Named
中通过Bind()
或通过扫描扩展,之后可以在实例化之前执行Module
子集绑定 - 尽管这不是你通常这样做)
- 必须实例化类型(Ninject:通常通过Resolve
,但如果您通过例如MEF发现类型,则可以使用Kernel.Get(Type)
overloads)
- 必须注入类型(Ninject:通常通过Kernel.Get()
,或隐含在`Kernel.Get())
我还不清楚为什么你觉得你需要混合和破坏这两者 - 最终在构造和构造函数注入期间共享任务不是lib的核心用例,即使它们都是非常可组合的库。您是否有约束力,或双方都有重大利益?
答案 1 :(得分:0)
您可以使用ExportFactory创建实例 看这里的文档:
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 希望这有帮助