tags:

views:

118

answers:

1

I have an application (just a test) which uses MEF and PRISM.

It's quite easy to load some exports that conform to specific interfaces and pass them to the constructor of the modules that are being loaded, but I'm trying to do something different.

When the application starts, it imports an implementation of IControllerClient. The created instance then needs to be configured (by the shell for example) after which every module in the application should have access to it.

I don't want to have a public property on the Shell or some helper class which exposes this instance as that would probably be considered a bad practice... and I don't really like it.

Update: rephrasing the question below

We have a number of interfaces defined in an existing framework, normally these are loaded using MEF into various applications.

I was able to load them into a module in a prism application, for example like this:

[ImportingConstructorAttribute()]
public HelloWorldView(IDataTransportService dataTransportService,
                      IMessageFactory messageFactory,
                      IDataFactory dataFactory,
                      IDataProcessor dataProcessor,
                      IDataCollector dataCollector)
{
        var client = new ControllerClient(dataTransportService,
                                          messageFactory,
                                          dataProcessor
                                          dataCollector);
}

In this case the module creates a valid instance of the ControllerClient class.

But instead of passing those interfaces to the constructor, I want to have a module constructor like this:

[ImportingConstructorAttribute()]
public HelloWorldView(IClient client)
{
   this.client = client;
}

The constructor for the IClient implementation (ControllerClient) has the [ImportingConstructorAttribute()] so I expected the depencencies to be injected automatically at this point... however using this code, the constructor is never even reached.

What I want is to have one instance of an IClient interface which is used by ALL modules in the application. (I understand now Shared is the default for MEF imports).

What's the best way to do this? Why can't I have a module constructor taking an IClient, and what if I wanted to expose an instance of a class this way if it does not have knowledge of mef?

So in a mef/prism app, where would you define this instance which can be used by all modules? And is this what is often referred to as a Service (but I could only find guidance on exposing services with unity/prism).

I hope I did a better job at explaining my problem this time.

Update 2: Since the default is shared for MEF imports, I could import the IClient implementation in every module, but then I need to figure out why the dependencies are not injected

+1  A: 

For MEF, Shared is the default, so every import of an interface will resolve to the same instance. The configuration of that instance can occur in the constructor of the class or you can implement IPartImportsSatisfiedNotification on your 'singleton' service class, which will call back when MEF has finished resolving your class imports.


Reading your updated description, it sounds like you can't configure the class in its constructor or after its Imports have been resolved, as you need some additional context information. If this is the case, what you can do is configure the class manually in your Shell and manually add the Export after it's been created using the container's ComposeParts method. This will make your 'configured' instance the one that will be used for resolving any [Export] tags you've applied to the class. Of course you'll have to do this before you construct anything else through the container that would depend on the instance.

Dan Bryant
@Dan I will try that, sounds reasonable :)
TimothyP
Works like a charm. I used Container.ComposeExportedValue(client); in my mef bootstrapper class after the client instance has been configured. Now the constructors of the module simply take a client :-) Thank you !
TimothyP