Prism ServiceLocator GetInstance和MEF

use*_*152 3 c# prism mef

我正在尝试使用Microsoft.Practices.ServiceLocation.ServiceLocator和MEF.接口IServiceLocator使用两个参数定义方法GetInstance.第一个参数是serviceType,第二个参数是关键.

我有两个实现接口IMyInterface的类,它们具有Export属性:

[Export(typeof(IMyInterface)), PartCreationPolicy(CreationPolicy.Shared)]
public class Class1 : IMyInterface 
{}

[Export(typeof(IMyInterface)), PartCreationPolicy(CreationPolicy.Shared)]
public class Class2: IMyInterface 
{}
Run Code Online (Sandbox Code Playgroud)

我想通过Prism ServiceLocator GetInstance方法获取Class1的实例:

ServiceLocator.Current.GetInstance(typeof(IMyInterface),"Key");
Run Code Online (Sandbox Code Playgroud)

但我不知道应该如何定义"关键".我试图在export属性中定义键:

[Export("Key1",typeof(IMyInterface)), PartCreationPolicy(CreationPolicy.Shared)]
public class Class1 : IMyInterface 
{}

[Export("Key2",typeof(IMyInterface)), PartCreationPolicy(CreationPolicy.Shared)]
public class Class2: IMyInterface 
{}
Run Code Online (Sandbox Code Playgroud)

当我用关键参数调用方法GetInstance时

ServiceLocator.Current.GetInstance(typeof(IMyInterface),"Key1");
Run Code Online (Sandbox Code Playgroud)

我得到Microsoft.Practices.ServiceLocation.ActivationException(尝试获取IMyInterface类型的实例,键"Key1"时发生激活错误).有人知道如何定义导出键吗?谢谢

Adi*_*ter 6

棱镜使用MefServiceLocatorAdapter于MEF的适应CompositionsContainerIServiceLocator接口.这是它用来获取您的部分的实际代码:

protected override object DoGetInstance(Type serviceType, string key)
{
    IEnumerable<Lazy<object, object>> exports = this.compositionContainer.GetExports(serviceType, null, key);
    if ((exports != null) && (exports.Count() > 0))
    {
        // If there is more than one value, this will throw an InvalidOperationException, 
        // which will be wrapped by the base class as an ActivationException.
        return exports.Single().Value;
    }

    throw new ActivationException(
        this.FormatActivationExceptionMessage(new CompositionException("Export not found"), serviceType, key));
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,您正在GetInstance正确导出和调用.但是,我认为您的服务定位器设置不正确,这就是您获得此异常的原因.如果您正在使用Prism MefBootstrapper来初始化您的应用程序,那么这应该已经为您完成了.否则,您需要使用此代码对其进行初始化:

IServiceLocator serviceLocator = new MefServiceLocatorAdapter(myCompositionContainer);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
Run Code Online (Sandbox Code Playgroud)