Service Locator works from app but not dynamically-instantiated class

762 views Asked by At

My app registers a bunch of view models this way:

static App()
{
   GalaSoft.MvvmLight.Threading.DispatcherHelper.Initialize();
   Microsoft.Practices.ServiceLocation.ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
}

private void Application_Startup(object sender, StartupEventArgs e)
{
   SimpleIoc.Default.Register<ViewModelA>();
   ...
}

and I'm able to access ViewModelA using:

ServiceLocator.Current.GetInstance<ViewModelA>()

But when the app executes:

obj = (MyClass)Activator.CreateInstance(typeof(MyClass);

to instantiate a class from a plugin assembly, its constructor executes:

public MyClass()
{
   SimpleIoc.Default.Register<ViewModelB>();
   var vm = SimpleIoc.Default.GetInstance<ViewModelB>();
   var serviceLocator = ServiceLocator.Current;
   var referenceSetUpTabViewModel = serviceLocator.GetInstance<ViewModelB>();

   InitializeComponent();
}

ViewModelB is currently just an empty class:

public class ViewModelB
{
}

The vm variable contains an instance of ViewModelB and serviceLocator variable equals GalaSoft.MvvmLight.Ioc.SimpleIoc but the serviceLocator.GetInstance line throws exception:

An exception of type 'Microsoft.Practices.ServiceLocation.ActivationException' occurred in GalaSoft.MvvmLight.Extras.dll but was not handled in user code

Additional information: Type not found in cache: ViewModelB

Since the vm variable was set, it would seem the type was registered successfully, so why can't the service locator get it?

Besides making it easier to switch to a different container, is there some other reason it is recommended to use ServiceLocator? I've isolated my uses of the container to Application_Startup and a ViewModelLocator class, so if I do choose something more heavy-weight than SimpleIoc in the future, it would be pretty trivial to migrate.

Using Microsoft VS2013 Update 4, .NET 4.5.2, MVVM-Light 5.1.1, CommonServiceLocator 1.3.

1

There are 1 answers

0
Jim C On

I don't know why but today the problem I posted about is no longer occurring...the dynamically-loaded assembly can now execute ServiceLocator.Current.GetInstance(); without throwing an exception. If I can get it back into the failing state, I will add the root cause to this answer for future reference.