MEF构造函数注入
我想弄清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);
}
这里是我想要当您使用ImportingConstructor属性,参数来构造成为进口加载
[Serializable]
[Export(typeof(BUsers))]
public class EditProfile : BUsers
{
[ImportingConstructor]
public EditProfile(string Method, string Version)
{
Version = "2";
Action = "Edit";
TypeName = "EditProfile";
}
类。默认情况下,您导入的内容(合同名称)基于您要导入的参数或属性的类型。因此,在这种情况下,您的导入的合同类型是字符串,并且第一个和第二个参数之间没有实际差异。
它看起来像你正在尝试使用导入来提供配置值,这不一定是它的设计目的。为了得到它做你想要什么,你应该为每个参数的重写合同的名称,如:
[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类中定义的扩展方法。)
如果你想从配置读取这些值可以创建自己的导出提供程序,该提供程序读取配置并提供其中的值作为导出到容器。
处理这种情况的另一种方法是只导入一个接口,该接口通过名称提供对配置值的访问,并从构造函数的主体中获取所需的值。
我喜欢丹尼尔的解决方案;然而,我所看到的只有一件事是参与者名称(创建CompopositionContrainer())和导出部分与[ImportingConstructor]之间的自定义CTOR紧密耦合。例如,“方法”在两个地方都有两个匹配。如果参与者和导出部分处于差异项目中,则难以维护导出部分。
如果可能,我会将第二个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; }
}
关键的一点是要导出的属性添加到类。然后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的鲜为人知的功能的另一种方法:房产出口
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也不需要任何属性。
不错的功能,但如果'EditProfile'包含任何导入?在这种情况下,您需要在容器上调用“SatisfyImportsOnce”。这很痛。目前我对这个问题没有真正的解决方案。 – 2015-10-13 14:38:50
在这种情况下,我们正在构建一个手动实例化EditProfile的工厂。如果EditProfile在构造函数中需要额外的依赖关系,则可以通过ImportingConstructor始终将这些依赖关系带入Factory。我应该指出,如果向EditProfile添加其他依赖项,这是应用程序中此构造函数的唯一引用,并且您将收到编译时错误。这是一个公平交易,恕我直言。 – bryanbcook 2015-10-14 18:00:29
我刚刚在CodePlex上下载了一个新的。 ComposeExportedValue()的方法不在CompositionContainer的类中。它在哪里? – 2010-01-20 22:18:51
我想我找到了方法。它属于AttributedModelServices类,其中方法被定义为类CompositionContainer的扩展方法。 – 2010-01-20 22:32:20
@ David.Chu.ca是的,ComposeExportedValue是AttributedModelServices类的扩展方法。 – 2010-01-21 18:33:14