MEF构造器注入

我试图找出MEF的构造函数注入属性。 我不知道如何告诉它加载构造函数的参数。

这是我正在尝试加载的属性

[ImportMany(typeof(BUsers))] public IEnumerable<BUsers> LoadBUsers { get; set; } 

这是我用来导入程序集的代码。

 try { var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); catalog.Catalogs.Add(new DirectoryCatalog("DI")); var container = new CompositionContainer(catalog); container.ComposeParts(this); } 

这是我正在尝试加载的课程

 [Serializable] [Export(typeof(BUsers))] public class EditProfile : BUsers { [ImportingConstructor] public EditProfile(string Method, string Version) { Version = "2"; Action = "Edit"; TypeName = "EditProfile"; } 

当您使用ImportingConstructor属性时,构造函数的参数将成为导入。 默认情况下,您导入的内容(合同名称)基于您要导入的参数或属性的types。 因此,在这种情况下,您的导入的合同types是string,而第一个和第二个参数之间没有实际的区别。

看起来您正在尝试使用导入来提供configuration值,这不一定是为其devise的。 要让它做你想做的,你应该覆盖每个参数的合同名称,如下所示:

 [ImportingConstructor] public EditProfile([Import("Method")] string Method, [Import("Version")] string Version) { } 

然后,您需要在容器中输出“方法”和“版本”。 一种方法是直接添加它们:

 var container = new CompositionContainer(catalog); container.ComposeExportedValue("Method", "MethodValue"); container.ComposeExportedValue("Version", "2.0"); container.ComposeParts(this); 

(请注意,ComposeExportedValue实际上是在静态AttributedModelServices类上定义的扩展方法。)

如果要从某种configuration文件读取这些值,可以创build自己的导出提供程序,该提供程序读取configuration,并将其中的值作为导出到容器中。

处理这种情况的另一种方法是只导入一个接口,通过名称访问configuration值,并从构造函数的主体中获取所需的值。

我喜欢丹尼尔的解决scheme; 然而,我所看到的只有一件事是参与者名称(创buildCompopositionContrainer())和导出部分之间的紧密耦合,以及用于自定义CTOR的[ImportingConstructor]。 例如,“方法”有两个匹配的地方。 如果参与者和导出部分处于差异项目中,则难以维护导出部分。

如果可能,我会将第二个CTOR添加到Export部件类中。 例如:

 [Export(typeof(BUsers))] public class EditProfile : BUsers { [ImportingConstructor] public EditProfile(EditProfileParameters ctorPars) : this(ctorPars.Method, ctorPars.Version) {} public EditProfile(string Method, string Version) { Version = "2"; Action = "Edit"; TypeName = "EditProfile"; } 

EditProfileParameters类应该很简单:方法和版本的两个属性:

 [Export] public class EditProfileParameters{ public string Method { get; set; } public string Version { get; set; } } 

关键点是将Export属性添加到类中。 然后MEF应该能够将这个类映射到EditProfile的CTOR的参数。

以下是将导出部件添加到容器的示例:

 var container = new CompositionContainer(catalog); var instance1 = new EditProfileParameters(); // set property values from config or other resources container.ComposeExportedValue(instance1); container.ComposeParts(this); 

虽然在游戏后期,这是另一种利用MEF:Property Exports中鲜为人知的特性的方法

 public class ObjectMother { [Export] public static EditProfile DefaultEditProfile { get { var method = ConfigurationManager.AppSettings["method"]; var version = ConfigurationManager.AppSettings["version"]; return new EditProfile(method,version); } } } 

ObjectMother不需要使用这个工具,EditProfile也不需要属性。

Interesting Posts