如何使用MefContrib或其他技术将N个MEF导出注入到一个Unity复合服务中
本文关键字:一个 服务 复合 Unity 注入 其他 MefContrib 何使用 技术 MEF | 更新日期: 2023-09-27 18:10:48
假设我有以下5个独立的程序集(假设每个类的名称不同):
[Export(typeof(IService))]
public class Service: IService
{
// ...
}
在我的主程序集中有一个类是这些的组合
public class CompositeService : IService
{
public CompositeService(IEnumerable<IService> services)
{
// ...
}
}
我想做的是让Unity容器为IService
解析CompositeService
,并为Unity提供MefContrib扩展,并找到其他5个出口并将它们注入CompositeService
的构造函数。
问题是你不能有N实例对于一个无名的unityContainer.RegisterType<IService>
,你也不能为命名的实例,如果他们都有相同的名称。
我想我错过了一些简单的结合两种技术(Unity + MEF)通过第三(MefContrib),但似乎不能拿起它是什么。
这是可能的还是有一个解决方案?最后,我将全面介绍双向依赖注入和动态组件发现。
我认为最好的方法可能是把它颠倒过来。而不是试图通过Unity注册你的组件,你实际上把这些部件的发现留给MEF。MEFContrib包含一个Unity集成机制,允许你的MEF组成部分被注入到Unity组件中。这是在Piotr WŁodek的博客上的原始细节,他也给了你一个样本。基本上,它的工作方式是您可以在UnityContainer
上使用一系列扩展方法来注册您的目录。在内部,它将创建适当的扩展并连接容器。
public interface IUnityComponent
{
IEnumerable<IMefComponent> MefComponents { get; }
}
public interface IMefComponent
{
string Name { get; }
}
然后是一些我们将导出的样本部件(通过MEF):
[Export(typeof(IMefComponent))]
public class MefComponent1 : IMefComponent
{
public string Name { get { return "MEF Component 1"; } }
}
[Export(typeof(IMefComponent))]
public class MefComponent2 : IMefComponent
{
public string Name { get { return "MEF Component 2"; } }
}
现在,我们将创建另一个部分(这将通过Unity创建):
public class UnityComponent : IUnityComponent
{
public UnityComponent(IEnumerable<IMefComponent> mefComponents)
{
// mefComponents should be provided from your MEF container.
MefComponents = mefComponents;
}
public IEnumerable<IMefComponent> MefComponents { get; private set; }
}
将其全部连接起来,我们只需要在UnityContainer
上使用RegisterCatalog
扩展方法(在添加对MEFContrib的引用后导入MefContrib.Integration.Unity
):
var container = new UnityContainer();
// Register the catalog - this handles MEF integration.
container.RegisterCatalog(new DirectoryCatalog("."));
// Register our Unity components.
container.RegisterType<IUnityComponent, UnityComponent>(new ContainerControlledLifetimeManager());
现在您应该能够获取实例并枚举mef提供的部分:
// Grab an instance of our component.
var instance = container.Resolve<IUnityComponent>();
foreach (var mefComponent in instance.MefComponents)
{
Console.WriteLine(mefComponent.Name);
}
注释: 100%未经测试。
刚刚从Matthew那里尝试了相同的解决方案,它工作正常,Unity正在从MEF中提取出口并将它们注入构造函数(接受IEnumerable<>)。
不知道它是否能帮助你,但包括MefContrib和MefContrib. integration . unity可以帮助:有一段时间我只包括后者,遇到了类似的错误。
作为一个边注,请记住,所有的注册在Unity(来自MEF导出)将是"无名的",所以如果你尝试ResolveAll<>你会得到一个空的集合,如果你尝试Resolve<>你会得到一个异常,如果有超过1实现注册