I am trying to get a Prism application to start up, and am getting a very strange error:
InvalidOperationException: ServiceLocationProvider must be set.
I am using MainWindow
in the main (module host) application as the region for a single main shell, that has it's own regions. That way I can swap out main window layouts if needed.
I get the error on the InitializeComponent();
call, the only line of code in the constructor of MainWindow
. Google and Bing both return zero results for that exact phrase.
The XAML element in MainWindow
is:
<ContentControl regions:RegionManager.RegionName="MainShellRegion" />
Do I have to implement some interface or something on MainWindow
to solve this? I am completely stumped.
You need to set up dependency injection for your Prism application, otherwise it won't be able to run. This should be done from inside your bootstrapper, inside the ConfigureServiceLocator
method.
To expand a bit on the above, Prism is wired so that whenever it needs access to an application component it does not initialize the component directly (how would it know which implementation to use and how to initialize it?) but rather it delegates this job to a service locator.
The service locator is a component whose responsibility is to fulfill requests for one component made by another, allowing the two components to be decoupled. It is your responsibility as the developer to instantiate and configure the service locator and make it available to Prism; this is done during application startup (hence inside the bootstrapper).
As Jon wrote, Prism needs the ServiceLocator to be set. This is done in the bootstrapper and should happen in the abstract ConfigureServiceLocator
method. The MefBootstrapper
or UnityBootstrapper
have an implementation for that method where the service locator is set based on the composition container (which itself is set in ConfigureContainer
).
These methods (and many more) are all called as part of the Run
method on the bootstrapper.
So my guess is that you are not calling the bootstrapper correctly. You code should look something like this:
public class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
var bootstrapper = new MyBootstrapper();
bootstrapper.Run();
}
}
Everything else should be done in the appropriate methods on the bootstrapper.