我以前的文章包含嘗試使用無屬性(基於約定)的方法來配置MEF:MEF 2: import many。
但它包含按條件(特定名稱,版本)進行延遲初始化插件所需的類PluginMetadataAttribute中的導出元數據屬性用法。
如何擺脫ExportAttribute的依賴?MEF無屬性方法:通過條件進行延遲初始化
回答
您在其他問題中引用的An Attribute-Free Approach to Configuring MEF文章包含有關如何在不使用屬性的情況下添加元數據的示例。
該示例顯示使用PartBuilder.ExportProperties過載,該過載將Action<PropertyInfo, ExportBuilder>
作爲參數,並使用重載之一爲特定導出添加元數據。
這不是添加元數據的唯一方法。所有導出方法PartBuilder都有一個超載,其中帶有ExportBuilder參數的Action<>
(或動作<,>)。您可以使用這些重載並以類似的方式添加元數據。
我找到了三個解決方案。
溶液1(使用類常數字段,溶液差):
public class Plugin1 : IPlugin
{
public const string Name = "Plugin1";
public const string Version = "1.0.0.0";
public void Run()
{
Console.WriteLine("Plugin1 runed");
}
}
// ...
var builder = new RegistrationBuilder();
builder
.ForTypesDerivedFrom<IPlugin>()
.Export<IPlugin>(exportBuilder => {
exportBuilder.AddMetadata("Name", t => t.GetField("Name").GetRawConstantValue());
exportBuilder.AddMetadata("Version", t => t.GetField("Version").GetRawConstantValue());
});
溶液2(使用類屬性,溶液差):
public interface IPluginMetadata
{
string Name { get; }
string Version { get; }
}
public interface IPlugin : IPluginMetadata
{
void Run();
}
public class Plugin1 : IPlugin
{
public string Name { get { return "Plugin 1"; } }
public string Version { get { return "1.0.0.0"; } }
public void Run()
{
Console.WriteLine("Plugin1 runed");
}
}
而由方法得到的屬性值描述了本:https://stackoverflow.com/a/11162876/1986524
解決方案3(使用屬性,更好但不是全部開心):
using System;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Registration;
using System.Reflection;
namespace MEF2
{
public interface IPluginMetadata
{
string Name { get; }
string Version { get; }
}
public interface IPlugin
{
void Run();
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginMetadataAttribute : Attribute, IPluginMetadata
{
public string Name { get; set; }
public string Version { get; set; }
public PluginMetadataAttribute(string name, string version)
{
Name = name;
Version = version;
}
}
[PluginMetadata("Plugin1", "1.0.0.0")]
public class Plugin1 : IPlugin
{
public void Run()
{
Console.WriteLine("Plugin1 runed");
}
}
[PluginMetadata("Plugin2", "2.0.0.0")]
public class Plugin2 : IPlugin
{
public void Run()
{
Console.WriteLine("Plugin2 runed");
}
}
class Program
{
static void Main(string[] args)
{
var builder = new RegistrationBuilder();
builder
.ForTypesDerivedFrom<IPlugin>()
.Export<IPlugin>(exportBuilder => {
exportBuilder.AddMetadata("Name", t => t.GetCustomAttribute<PluginMetadataAttribute>().Name);
exportBuilder.AddMetadata("Version", t => t.GetCustomAttribute<PluginMetadataAttribute>().Version);
});
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly(), builder);
using (var container = new CompositionContainer(catalog, CompositionOptions.DisableSilentRejection)) {
var plugins = container.GetExports<IPlugin, IPluginMetadata>();
foreach (var plugin in plugins) {
Console.WriteLine("{0}, {1}", plugin.Metadata.Name, plugin.Metadata.Version);
plugin.Value.Run();
}
}
}
}
}
解決方案3中包含此代碼的問題:
.Export<IPlugin>(exportBuilder => {
exportBuilder.AddMetadata("Name", t => t.GetCustomAttribute<PluginMetadataAttribute>().Name);
exportBuilder.AddMetadata("Version", t => t.GetCustomAttribute<PluginMetadataAttribute>().Version);
})
問題:
- 無法取消的情況下,添加缺少的元數據
- 重複的代碼
t.GetCustomAttribute<PluginMetadataAttribute>()
Export<>
的元數據不提供過濾器
如果有人知道其他解決方案,請寫信。
我更喜歡第三種解決方案。 1)您可以在lambda內添加一個if語句,並且只有在該屬性存在時才添加元數據。 2)而不是添加兩個元數據添加一個。整個PluginMetadata對象! 3)你有什麼樣的過濾方法? –
@PanosRontogiannis 1.是的,我加了檢查: 't => {var。attr = t。GetCustomAttribute
- 1. .Net Singleton屬性的延遲初始化
- 2. 使用@Transactional進行延遲初始化
- 3. 如何使用getter/setter方法進行延遲初始化?
- 4. 延遲初始化?
- 5. 延遲初始化
- 6. 延遲初始化
- 7. 用scala進行通用延遲初始化
- 8. 延遲初始化 - 無效參數
- 9. Sakai Hibernate延遲初始化
- 10. Tensorflow初始化延遲
- 11. 延遲初始化表
- 12. boost.serialization和延遲初始化
- 13. 延遲初始化 - 休眠
- 14. jQuery DataTables初始化延遲
- 15. 新的延遲初始化
- 16. 可空構件的延遲初始化
- 17. Phonegap插件延遲初始化
- 18. 如何使用MEF初始化方法
- 19. 使用聲明和延遲初始化屬性的錯誤
- 20. 使用延遲初始化屬性分離JPA對象
- 21. 未能延遲初始化收集...,無法初始化代理 - 沒有會話
- 22. NSManageObject子類無法通過alloc進行初始化?
- 23. Obexpushd無法通過藍牙進行初始化
- 24. 無法初始化QML屬性{}
- 25. 使用Spring IBatis對緩存進行延遲初始化
- 26. 在Singleton中如何進行延遲初始化?
- 27. 適合使用期貨和承諾進行延遲初始化?
- 28. 如何使用Kotlin中的參數進行延遲初始化
- 29. 緩存一個IEnumerable vs List進行延遲初始化
- 30. 使用方法初始化類屬性
據我瞭解我必須使用類的屬性繼承接口IPlugin: 公共類Plugin1:IPlugin { 公共字符串名稱{{返回「Plugin1」; }} public string Version {get {return「1.0.0.0」;}} }} 但如何從此屬性中提取數據並從ExportProperties傳遞給AddMetadata操作<,>? – anpv