How to register an object reference that passed from host app into hosted WPF using Prism

Topics: Prism v4 - WPF 4
Jul 27, 2011 at 2:26 PM

I'm implementing a WPF class library (dll) for a Win app. When this WPF is started, I need to pass some object references from the host Win app into WPF bootstrapper. How can I do this and register this object reference in the container so it can be injected to other modules? I've read the documentation but all it talk about is how to register a service (through) inside WPF. But in my case, this is not from WPF itself but passed in from the host and it some time is just a static class.

Thanks!

Developer
Jul 27, 2011 at 5:25 PM

Hi,

You could define a constructor in your Bootstsrapper class (which most likely inherits from MefBootstrapper or UnityBootstrapper), which accepts an instance of that service and stores it in a private field, and override its ConfigureContainer method to register it in the container.

Then, in the Application_Startup method in the App class located inside the App.xaml.cs file, you could instantiate your bootstrapper (passing your service as a parameter) and call it's Run method, just like you regularily do in a Prism application.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jul 27, 2011 at 10:56 PM

Thanks. That's helpful.

Follow up question,  

1. when I register this object reference, do I have to do it through interface, i.e. the class of the object reference has to implement interface? From code example, looks like it always has to have an interface. 

2. Should I use RegisterType or RegisterInstance?

 

Thanks.

Developer
Jul 28, 2011 at 4:38 PM
Edited Jul 28, 2011 at 5:05 PM

Hi,

The recommended approach when using shared services is to register the types or objects using interfaces. This way, the different components of you application (in this case the service and the components that will use it) will be loosely coupled, allowing you to mock the dependencies on the service in a unit test scenario or to change said service with another one without having to modify the dependent components. Of course, to do this the service should implement an interface.

Based on my understanding of your scenario, you should use the RegisterInstance method to register the service as a singleton. By doing this, when resolving the dependencies, the container will return always the same instance that you registered instead of trying to create a new one each time the dependencies are resolved.

This is because the whole purpose of my previous answer was to allow you to register a specific instance of a service (created before initializing the WPF application) into the container. If you wish to make the container return a new instance of the service each time you call the Resolve method, then you should abandon the workaround I’ve proposed in that answer.

You can find more information about the differences between RegisterType and RegisterInstace in the following articles:


I hope you find this useful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jul 29, 2011 at 12:24 AM

Your understanding was correct. I need to register the object instance for the whole lifetime. The links you posted made it clear. But the RegisterInstance if for UnityContainer, how to do it for MEF? Use attributes on the instance?

Developer
Jul 29, 2011 at 5:01 PM

Hi,

To register an instance of an object as a singleton when using MEF you can use the ComposeExportedValue method, as shown in the ConfigureContainer method of the QuickStartBootstrapper class in the Modularity with Mef QuickStart:

protected override void ConfigureContainer()

{

    base.ConfigureContainer();

    this.Container.ComposeExportedValue<CallbackLogger>(this.callbackLogger);

}

For more information about this you can check the section Registering Types With MEF of Chapter 3: Managing Dependencies Between Components.

Also, you should note that types exported inside your application using attributes with MEF are declared as singleton instances by default. If you want to control whether they are declared as a shared or a non-shared export, you can use the PartCreationPolicyAttribute.

 I hope you find this useful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi