代码之家  ›  专栏  ›  技术社区  ›  alpha

MEF构造函数注入

  •  38
  • alpha  · 技术社区  · 16 年前

    我试图找出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";
        }
    
    3 回复  |  直到 10 年前
        1
  •  58
  •   Jean Hominal    14 年前

    看起来您正试图使用导入来提供配置值,这不一定是它的设计目的。要使其执行所需操作,应覆盖每个参数的合同名称,如下所示:

    [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);
    

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

    处理此问题的另一种方法是只导入一个接口,该接口通过名称提供对配置值的访问,并从构造函数体获取所需的值。

        2
  •  24
  •   IAbstract    14 年前

    如果可能的话,我会将第二个CTOR添加到导出零件类中。例如:

    [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";
        }
    

    [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);
    
        3
  •  1
  •   bryanbcook    11 年前

    虽然起步较晚,但这里有另一种方法利用了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上的属性。