tags:

views:

39

answers:

2

Hi, I have an app based on Prism (v4 ctp) and MEF. The app has a service IService1. I want this service implementation was exported by some module (not just discovered by MEF)

public interface IService1 {}
public class Service1Impl: IService1 {}

Service1Impl doesn't have ExportAttribute. This' because I want to create the implementation by hand in my Prism-module:

[ModuleExport(typeof(SomeModule))]
[PartCreationPolicy(CreationPolicy.Shared)]
public SomeModule: IModule
{
    [Export]
    public IService1 Service1 {get; private set}

    public void Initialize()
    {
        Service1 = new Service1Impl();
    }
}

In some other components I want to get IService1's implementation through MEF Import. The problem is how to tell MEF to do export (in SomeModule) after Initialize was called by Prism?

If I create the service's implementation in the module's constructor then everything works fine, but it's inconsistent with Prism's modules initialization process. The thing is that Prism initializes modules after MEF's composition completes. Moreover before creation of the service's implementation I need to perform some complex initialization logic and I don't want it to be in constructor.

So, what are my options?

A: 

Have you tried a ModuleDependency? I need to do some more research on MEF, but in Prism, you can guarantee that one Module's Initialize fires before the others via a ModuleDependency.

For example, if you had SomeOtherModule that needed an IService1 during Initialize, you could make sure that SomeModule was initialized first this way.

[ModuleDependency("SomeModule")]
public class SomeOtherModule : IModule
{
    [Import]
    public IService1 Service1 {get; set;}

    public void Initialize()
    {
        //This ought to be populated now.
        Service1.DoSomething();
    }
}

I'm fully-qualifying this by saying I might not know some inner working of MEF that does not allow this, but this is how things work generally with Prism.

As an aside, when I see a dependency, whether it be explicit or implicit, I ask myself:

  1. Is the service going to be used by multiple modules? Does it then make sense to promote the service as something that is constructed in the Bootstrapper and provided by the hosting application and not another module?
  2. If not #1, if there is a dependency between modules, are these modules logically the same? Should they be combined? If one can't live without the other, there are few reasons not to combine them.

Anyway, that last is just something to think about.

Hope this helps.

Anderson Imes
Thanks, but honestly, I don't like this approach, as it creates dependencies between modules who export services and modules who imports services. It's not good I believe.
Shrike
@Shrike You have an implicit dependency already. You are expecting the service implementation to be provided by another module and some part of your process fails if it's not there. That's why I posted the "As an aside" section... you have a dependency between your modules that you need to address. I don't like ModuleDependency either, but you have to address an implied dependency in some manner. If not the ModuleDependency, then one of the other approaches I listed.
Anderson Imes
A: 

Hi,

I'm a bit rusty on my MEF usage, but these ideas might be useful. What if your property is of the concreate implementation type, but you export the property through a contract specifying the interface (I think it was similar to the following):

[Export(IService1)]
public Service1Impl Service1 {get; private set}

Then every module that has an import checking for the IService1 interface will get the concrete implementation from that module (which is the main goal of coding against the interface).

I hope this guides you in the right direction.

Thanks, Damian

Damian Schenkelman

related questions