getting error 'Microsoft.Practices.ServiceLoca

2019-04-16 00:32发布

问题:

I am Unit Testing MVVM based application that uses prism and using mocking to test view model . I am able to call the constructor of my viewmodel class by passing mock objects of region manager and resource manager but when control goes inside constructor it fails at the following statement :

private EventAggregator()
        {
            this.eventAggregatorInstance = ServiceLocator.Current.GetInstance<IEventAggregator>();
        }                                                                                 It gives error : An unhandled exception of type 'Microsoft.Practices.ServiceLocation.ActivationException' occurred in Microsoft.Practices.ServiceLocation.dll

Additional information: Activation error occured while trying to get instance of type IEventAggregator, key "". Please help how to resolve this.

回答1:

I see you solved your problem by adding the EventAggregator to your container.

However, I would suggest that your ViewModel should not be using the ServiceLocator to resolve the EventAggregator at all. The ServiceLocator is a glorified static instance that is basically an anti-pattern (see Service Locator is an Anti-Pattern). Your ViewModel should most likely accept the EventAggregator in the constructor via dependency injection and use it from there. I don't think you should need a container to test your ViewModels. You could just construct them with their constructors and pass them any mock implementations of their dependent objects (as parameters to the constructor).



回答2:

Based on my understanding, the Service Locator gets initialized when running and initializing the Bootstrapper. Therefore, the exception you are issuing would be caused by not having the Locator initialized.

I believe the following post would be useful considering the non-Prism alternative taking into account that you didn't run the Bootstrapper on the Unit Test scope:

  • EventAggregator and ServiceLocator Issue

You would need to set the EventAggregator in the Mock Container, and then set the Service Locator service for that container:

(Quoted from above link)

IUnityContainer container = new UnityContainer();

// register the singleton of your event aggregator

container.RegisterType( new ContainerControlledLifetimeManager() );

ServiceLocator.SetLocatorProvider( () => container );

I hope this helped you,

Regards.