简体   繁体   中英

Prism ServiceLocator GetInstance and MEF

I'm trying to use Microsoft.Practices.ServiceLocation.ServiceLocator and MEF. Interface IServiceLocator defines method GetInstance with two parameters. First parameter is serviceType and second paremeter is key.

I have two classes which implement interface IMyInterface and they have Export attribute:

ServiceLocator.Current.GetInstance(typeof(IMyInterface),"Key");

I want to get instance of Class1 via Prism ServiceLocator GetInstance method:

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

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

But I have no idea how and where should be "key" defined. I tried to define key in export attribute:

ServiceLocator.Current.GetInstance(typeof(IMyInterface),"Key1");

When I call method GetInstance with key parameter

 ServiceLocator.Current.GetInstance(typeof(IMyInterface),"Key1"); 

I get Microsoft.Practices.ServiceLocation.ActivationException (Activation error occured while trying to get instance of type IMyInterface, key "Key1"). Does anybody know how can be the export key defined? Thanks

Prism uses MefServiceLocatorAdapter to adapt MEF's CompositionsContainer to the IServiceLocator interface. This is the actual code that is used by it to get your part:

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));
}

So as you can see, you're exporting and calling GetInstance correctly. However, I believe your service locator isn't set up correctly, and that's why you're getting this exception. If you're using Prism's MefBootstrapper to initialize your application, this should already be done for you. Otherwise, you'll need to use this code to initialize it:

IServiceLocator serviceLocator = new MefServiceLocatorAdapter(myCompositionContainer);
ServiceLocator.SetLocatorProvider(() => serviceLocator);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM