假设我有一个接口ITest
:
public interface ITest
{
void PrintMachineInfo();
}
还有两个实现:
[Export("MachineName", typeof(ITest))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class Test1 : ITest
{
public void PrintMachineInfo()
{
Console.WriteLine(Environment.MachineName);
}
}
[Export(typeof(ITest))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class Test2 : ITest
{
public void PrintMachineInfo()
{
Console.WriteLine(Environment.OSVersion);
}
}
然后,我尝试检索ITest
的所有实例:
var foo = ServiceLocator.Current.GetAllInstances<ITest>();
foreach (var test in foo)
{
test.PrintMachineInfo();
}
事实证明,只能返回Test2
的实例。由于合同名称,它无法找到Test1
的实例。
我使用MEF + ServiceLocator + MefAdapter来运行所有这些内容。在我的调试中,MefAdapter会覆盖DoGetAllInstances(Type serviceType)
中的方法ServiceLocatorImplBase
,但它只提供一个参数serviceType
。
那么,无论实现是否已导出联系人名称,如何使用ServiceLocator获取ITest
的所有实例?
答案 0 :(得分:0)
使用Prism提供的IServiceLocator
的当前实现是不可能实现的。
该实现中重写的DoGetAllInstances()
方法调用GetExport()
方法的最后一次重载:
this.compositionContainer.GetExports(serviceType, null, null);
根据MSDN,第三个参数是
contractName :要返回的Lazy对象的合约名称,或 null 或空字符串(&#34;&#34) ;)使用默认合同名称。
正如您在本主题的评论中所看到的那样:
默认合约名称是调用GetContractName的结果 关于类型的方法。
该默认合约名称基于完整类型名称,不含任何其他键。这就是为什么你只得到第二个导出:它有默认的合同名称。
因此,如果不完全了解所有合同密钥,就无法以这种方式获得所有出口。
要提供多个导出,同时能够区分它们,您可以为每个导出提供其他元数据并保留相同的导出合同名称:
[Export(typeof(ITest))]
[ExportMetadata("Type", "MachineName")]
public class Test1 : ITest { }
[Export(typeof(ITest))]
[ExportMetadata("Type", string.Empty)]
public class Test2 : ITest { }