m-y m-y - 2 months ago 17
C# Question

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?

Answer

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));
Comments