在MEF中组成零件

时间:2011-09-13 07:41:38

标签: .net ioc-container mef composition

考虑以下情况:

[Export]
class A { }

class B 
{
  [Import]
  private A a;
}

// Instantiates class B.
class C 
{   
  public C(Type type){ /*Instantiate Class B here.*/}

  public void PerfomOperationUsingClassB() { }
}

class D
{
  void Initialize()
  {
    var catalog = new AssemblyCatalog(Assembly.GetAssembly(typeof(A)));
    var container = new CompositionContainer(catalog);

    // Is there any way to compose A with B?

    C c = new C(typeof(B));
    c.PerfomOperationUsingClassB();
  }
}

问题:我可以访问类“A”和“B”,但类“C”位于我无法修改的程序集中(因此无法修改类“C”)。有没有办法组成“A”和“B”?

3 个答案:

答案 0 :(得分:1)

我不这么认为,不是没有引用B的实例......

如果您有参考资料,可致电:

container.SatisfyImportsOnce(instanceOfB);

答案 1 :(得分:1)

不幸的是,如果无法访问C的构造函数,你几乎没有运气。 C的构造函数似乎想要使用类型本身初始化B的实例...它是否提供了拦截B CC初始化的任何机制?

如果B要接受B的实例,您可以轻松地将C的组合实例传入构造函数。如果您要导出已关闭的类型public class MefAdapter<T, TExport> { private readonly Func<T, TExport> _factory = CreateFactory(); private readonly T _arg; [ImportingConstructor] public MefAdapter(T arg) { _arg = arg; } [Export] public TExport Export { get { return _factory(_arg); } } internal static Func<T, TExport> CreateFactory() { var tArg = typeof(T); var tExport = typeof(TExport); var arg = Expression.Parameter(tArg, "arg"); var ctor = tExport.GetConstructor(new[] { tArg }); var ctorExp = Expression.New(ctor, arg); return Expression.Lamda<Func<T, TExport>>(ctorExp, arg).Compile(); } } ,则可以执行以下操作:

C

(这是基于Mark Seemann's Resolving closed types文章)。

有了这个,public class C { public C(B b) { } } 实际应该是这样的:

B

您可以通过自动创建var typeCatalog = new TypeCatalog(typeof(MefAdapter<C>)); var catalog = new AggregateCatalog(new DirectoryCatalog("."), typeCatalog); var container = new CompositionContainer(catalog); var c = container.ComposeExportedValue<C>(); // This instance of C should have a composed instance of B injected. 来满足该关闭类型:

{{1}}

答案 2 :(得分:0)

您可以像class B这样使用ServiceLocator

class B
{
  private A a;

  B()
  {
    a = Microsoft.Practices.ServiceLocator.Current.GetInstance<A>();
  }
}