考虑以下情况:
[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”?
答案 0 :(得分:1)
我不这么认为,不是没有引用B的实例......
如果您有参考资料,可致电:
container.SatisfyImportsOnce(instanceOfB);
答案 1 :(得分:1)
不幸的是,如果无法访问C
的构造函数,你几乎没有运气。 C
的构造函数似乎想要使用类型本身初始化B
的实例...它是否提供了拦截B
C
内C
初始化的任何机制?
如果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>();
}
}