Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

mef

prism

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?

like image 846
myermian Avatar asked Nov 09 '22 09:11

myermian


1 Answers

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));
like image 138
Adi Lester Avatar answered Nov 14 '22 22:11

Adi Lester