myermian
myermian

Reputation: 32505

Is it possible to use MEF RegistrationBuilder to create a PRISM ModuleExport?

I'm working on a sample PRISM application and I want to use the MEF RegistrationBuilder to create all of my exports. The equivalent of using the ExportAttribute is as follows:

[Export(typeof(IFooService))]
public class FooService : IFooService { ... }

Builder.ForTypesMatching(typeof(IFooService).IsAssignableFrom(type)).Export<IFooService>();

However, modules use a different attribute, the ModuleExportAttribute, for example:

[ModuleExport(typeof(ModuleA), DependsOnModuleNames = new string[] { "ModuleB" })]
public sealed class ModuleA : IModule { ... }

I'm not sure how to use the RegistrationBuilder class to create the module export instead of using the ModuleExportAttribute. Is this even possible since it is exported differently than a standard export?

Upvotes: 5

Views: 496

Answers (1)

Adi Lester
Adi Lester

Reputation: 25201

The ModuleExport attribute is essentially just an Export(typeof(IModule)) atttibute with type-safe metadata (IModuleExport). You can easily "copy" its behavior with RegistrationBuilder by adding this metadata yourself. For example

RegistrationBuilder builder = new RegistrationBuilder();
builder.ForType<ModuleA>().Export<IModule>(eb => eb
   .AddMetadata("DependsOnModuleNames", new string[] { "ModuleB" })
   .AddMetadata("InitializationMode", InitializationMode.WhenAvailable)
   .AddMetadata("ModuleName", "ModuleA")
   .AddMetadata("ModuleType", typeof(ModuleA)));

You can verify this works by importing your modules like so, which is basically what Prism does behind the scenes:

[ImportMany]
Lazy<IModule, IModuleExport>[] Modules { get; set; }

You should note that you must specify in the metadata all the properties in the IModuleExport interface, or the modules will not be imported (as they don't satisfy the IModuleExport interface)


Adding to the answer:

The code above is the correct, working way; the code below looks correct, but does not work.

It's important to note that this only works if you utilize the PartBuilder.Export(Action<ExportBuilder> exportConfiguration) overload.

RegistrationBuilder builder = new RegistrationBuilder();
builder.ForType<ModuleA>().Export<IModule>()
   .AddMetadata("DependsOnModuleNames", new string[] { "ModuleB" })
   .AddMetadata("InitializationMode", InitializationMode.WhenAvailable)
   .AddMetadata("ModuleName", "ModuleA")
   .AddMetadata("ModuleType", typeof(ModuleA));

Upvotes: 1

Related Questions