gpt4 book ai didi

c# - MEF,我可以导出/导入具有多个 MetaDataAttribute 装饰的类吗?

转载 作者:太空宇宙 更新时间:2023-11-03 20:13:57 25 4
gpt4 key购买 nike

如何使下面的代码工作?它抛出一个错误,指出有两个名称相同的元数据属性,但我不明白为什么。

错误信息如下:

System.ComponentModel.Composition.dll 中发生类型为“System.InvalidOperationException”的未处理异常

附加信息:成员或类型“ConsoleApplication2.DoSomeMagic”包含多个名为“PluginName”的元数据条目。元数据条目可能来自 ExportMetadataAttribute 或来自自定义元数据属性的属性。删除重复条目或启用名称为“PluginName”的元数据条目,以允许通过 ExportMetadataAttribute 上的 IsMultiple 属性或自定义元数据属性上的 AttributeUsage.AllowMultiple 允许多个条目。

class Program
{
static void Main(string[] args)
{
var program = new Program();
program.Test();
}

private void Test()
{
//Export
var catalog = new AssemblyCatalog(this.GetType().Assembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);

//Import Meta Data
var import1 = container.GetExports<IMagic1, IPluginAttributeView>().Select(e => new PluginAttribute(e.Metadata));

}
}

public interface IPluginAttributeView
{
string PluginName { get; set; }
string PluginConfigurationName { get; set; }
string PluginCategory { get; set; }
Type PluginType { get; set; }
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginAttribute1 : ExportAttribute, IPluginAttributeView
{
public string PluginName { get; set; }
public string PluginConfigurationName { get; set; }
public string PluginCategory { get; set; }
public Type PluginType { get; set; }

public PluginAttribute1(string pluginName, string pluginConfigurationName, string pluginCategory, Type pluginType)
: base(pluginType)
{
PluginName = pluginName;
PluginConfigurationName = pluginConfigurationName;
PluginCategory = pluginCategory;
PluginType = pluginType;
}
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginAttribute2 : ExportAttribute, IPluginAttributeView
{
public string PluginName { get; set; }
public string PluginConfigurationName { get; set; }
public string PluginCategory { get; set; }
public Type PluginType { get; set; }

public PluginAttribute2(string pluginName, string pluginConfigurationName, string pluginCategory, Type pluginType) : base(pluginType)
{
PluginName = pluginName;
PluginConfigurationName = pluginConfigurationName;
PluginCategory = pluginCategory;
PluginType = pluginType;
}
}

public class PluginAttribute
{
public string PluginName { get; set; }
public string PluginConfigurationName { get; set; }
public string PluginCategory { get; set; }
public Type PluginType { get; set; }

public PluginAttribute(IPluginAttributeView view)
{
PluginName = view.PluginName;
PluginConfigurationName = view.PluginConfigurationName;
PluginCategory = view.PluginCategory;
PluginType = view.PluginType;
}
}


public interface IMagic1
{
void DoMagic1();
}

public interface IMagic2
{
void DoMagic2();
}

[PluginAttribute1("PluginName1", "PluginConfig1.json", "Magic1", typeof(IMagic1))]
[PluginAttribute2("PluginName2", "PluginConfig2.json", "Magic2", typeof(IMagic2))]
public class DoSomeMagic : IMagic1, IMagic2
{
public void DoMagic1()
{

}

public void DoMagic2()
{

}
}

最佳答案

我在翻阅了许多与 MEF 相关的博客和文章后找到了解决方案。问题似乎是导入的元数据类型为 IDictionary<string, object .我希望它能帮助一些可能遇到类似问题的人:

class Program
{
static void Main(string[] args)
{
var program = new Program();
program.Test();
}

private void Test()
{
//Export
var catalog = new AssemblyCatalog(this.GetType().Assembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);

//Import Meta Data
var imports = container.GetExports<IMagic1, PluginAttributeView>().Select(e => e.Metadata.Attributes).ToList();

var results = new List<PluginAttribute>();
foreach (var import in imports)
{
foreach (var plugin in import)
{
if (plugin.PluginType.Equals(typeof(IMagic1)))
{
results.Add(plugin);
}
}
}
}
}

public interface IPluginAttributeView
{
string PluginName { get; set; }
string PluginConfigurationName { get; set; }
string PluginCategory { get; set; }
Type PluginType { get; set; }
}

public class PluginAttributeView
{
public List<PluginAttribute> Attributes { get; set; }

public PluginAttributeView(IDictionary<string, object> aDict)
{
string[] p1 = aDict["PluginName"] as string[];
string[] p2 = aDict["PluginConfigurationName"] as string[];
string[] p3 = aDict["PluginCategory"] as string[];
Type[] p4 = aDict["PluginType"] as Type[];

Attributes = new List<PluginAttribute>();
for (int i = 0; i < p1.Length; i++)
{
Attributes.Add(new PluginAttribute(p1[i], p2[i], p3[i], p4[i]));
}
}
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class PluginAttribute : ExportAttribute, IPluginAttributeView
{
public string PluginName { get; set; }
public string PluginConfigurationName { get; set; }
public string PluginCategory { get; set; }
public Type PluginType { get; set; }

public PluginAttribute(string pluginName, string pluginConfigurationName, string pluginCategory, Type pluginType) : base(pluginType)
{
PluginName = pluginName;
PluginConfigurationName = pluginConfigurationName;
PluginCategory = pluginCategory;
PluginType = pluginType;
}
}

public interface IMagic1
{
void DoMagic1();
}

public interface IMagic2
{
void DoMagic2();
}

[PluginAttribute("PluginName1", "PluginConfig1.json", "Magic1", typeof(IMagic1))]
[PluginAttribute("PluginName2", "PluginConfig2.json", "Magic2", typeof(IMagic2))]
public class DoSomeMagic : IMagic1, IMagic2
{
public void DoMagic1()
{

}

public void DoMagic2()
{

}
}

关于c# - MEF,我可以导出/导入具有多个 MetaDataAttribute 装饰的类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18132821/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com