alp*_*pha 39 c# dependency-injection mef constructor-injection
我试图找出MEF的构造函数注入属性.我不知道如何告诉它加载构造函数的参数.
这是我正在尝试加载的属性
[ImportMany(typeof(BUsers))]
public IEnumerable<BUsers> LoadBUsers { get; set; }
Run Code Online (Sandbox Code Playgroud)
这是我用来导入程序集的代码.
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);
}
Run Code Online (Sandbox Code Playgroud)
这是我正在尝试加载的类
[Serializable]
[Export(typeof(BUsers))]
public class EditProfile : BUsers
{
[ImportingConstructor]
public EditProfile(string Method, string Version)
{
Version = "2";
Action = "Edit";
TypeName = "EditProfile";
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ted 55
使用ImportingConstructor属性时,构造函数的参数将成为导入.默认情况下,您导入的内容(合同名称)基于您要导入的参数或属性的类型.因此,在这种情况下,两个导入的合约类型都是字符串,并且第一个和第二个参数之间没有真正的区别.
看起来您正在尝试使用导入来提供配置值,这不一定是它的设计目标.为了让它做你想做的事,你应该覆盖每个参数的合同名称,如下所示:
[ImportingConstructor]
public EditProfile([Import("Method")] string Method, [Import("Version")] string Version)
{ }
Run Code Online (Sandbox Code Playgroud)
然后,您需要在容器中导出方法和版本.一种方法是直接添加它们:
var container = new CompositionContainer(catalog);
container.ComposeExportedValue("Method", "MethodValue");
container.ComposeExportedValue("Version", "2.0");
container.ComposeParts(this);
Run Code Online (Sandbox Code Playgroud)
(请注意,ComposeExportedValue实际上是在静态AttributedModelServices类上定义的扩展方法.)
如果要从某种配置文件中读取这些值,可以创建自己的导出提供程序,该提供程序读取配置并将其中的值作为导出到容器.
处理此问题的另一种方法是只导入一个按名称访问配置值的接口,并从构造函数体中获取所需的值.
Dav*_*.ca 24
我喜欢丹尼尔的解决方案; 但是,我看到的只有一件事是参与者名称(创建CompopositionContrainer())和导出部件与[ImportingConstructor]之间的紧密耦合,用于自定义CTOR.例如,"Method"在两个地方都有两个匹配.如果actor和Export部分位于不同的项目中,则很难维护Export部分.
如果可能的话,我会将第二个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";
}
Run Code Online (Sandbox Code Playgroud)
EditProfileParameters类应该是直截了当的:Method和Version的两个属性:
[Export]
public class EditProfileParameters{
public string Method { get; set; }
public string Version { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
关键是将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);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
36458 次 |
最近记录: |