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也不需要属性。