1

If I have multiple implementations of same interface

[Export("DALREMOTE", typeof(IDAL))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DAL : IDAL

and

[Export("DALLOCAL", typeof(IDAL))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DAL : IDAL

is there any way of programmatically choosing which implementation to use as standard in the constructor of modules.

[ImportingConstructor]
public ShellViewModel(IDAL dal........

Im using the PRISM/MEF bootstrapper and I though I could maybe put it there

klashagelqvist
  • 1,251
  • 2
  • 26
  • 52

1 Answers1

1

Since you are using contract names, you can specify the contract name as part of an ImportAttribute on the specific parameter.

Here's an example using the "DALLOCAL" contract name:

[ImportingConstructor]
public ShellViewModel([Import("DALLOCAL")]IDAL dal........

The ImportAttribute can be used to decorate parameters as well as properties.

Since, according to your comment, you do not want to use contract names and want to be able to select the implementation at runtime from some kind of app configuration, you can use export metadata. Here's an example using weak metadata:

[Export("DALREMOTE", typeof(IDAL))]
[ExportMetadata("Tag", "DALREMOTE")]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DAL : IDAL

[Export("DALLOCAL", typeof(IDAL))]
[ExportMetadata("Tag", "DALLOCAL")]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DAL : IDAL

Note that "Tag" is an arbitrary key. Also note that you can keep the named contract if you need it on other parts of your program.

The constructor becomes:

[ImportingConstructor]
public ShellViewModel([ImportMany]IEnumerable<Lazy<IDAL, IDictionary<string, object>>> dals)
{
    if (dals == null) throw new ArgumentNullException("dals");

    //Get the tag from your apps configuration.
    string tagFromConfiguration = ........

    _dal = dals.Where(l => l.Metadata["Tag"].Equals(tagFromConfiguration )).Single().Value;
}

The main difference here is that instead of a single IDAL, a sequence of IDALs is injected. Then in the .ctor you will have to select the IDAL you want. Note that the use of Enumerable.Single will work only if there is a single exported IDAL with a specific tag value.

The Exports and Metadata guide from MEF's Codeplex docs includes a lot of helpful examples.

Panos Rontogiannis
  • 4,154
  • 1
  • 24
  • 29
  • Didn't know that , thanks. Thing is I need it to be configured from an application setting so I can switch at runtime, if I take above approach I need to recompile application – klashagelqvist Jul 01 '13 at 14:43