2013-01-22 35 views

回答

2

您在其他問題中引用的An Attribute-Free Approach to Configuring MEF文章包含有關如何在不使用屬性的情況下添加元數據的示例。

該示例顯示使用PartBuilder.ExportProperties過載,該過載將Action<PropertyInfo, ExportBuilder>作爲參數,並使用重載之一爲特定導出添加元數據。

這不是添加元數據的唯一方法。所有導出方法PartBuilder都有一個超載,其中帶有ExportBuilder參數的Action<>(或動作<,>)。您可以使用這些重載並以類似的方式添加元數據。

+0

據我瞭解我必須使用類的屬性繼承接口IPlugin: 公共類Plugin1:IPlugin { 公共字符串名稱{{返回「Plugin1」; }} public string Version {get {return「1.0.0.0」;}} }} 但如何從此屬性中提取數據並從ExportProperties傳遞給AddMetadata操作<,>? – anpv

3

我找到了三個解決方案。
溶液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); 
}) 

問題:

  1. 無法取消的情況下,添加缺少的元數據
  2. 重複的代碼t.GetCustomAttribute<PluginMetadataAttribute>()
  3. Export<>的元數據不提供過濾器

如果有人知道其他解決方案,請寫信。

+0

我更喜歡第三種解決方案。 1)您可以在lambda內添加一個if語句,並且只有在該屬性存在時才添加元數據。 2)而不是添加兩個元數據添加一個。整個PluginMetadata對象! 3)你有什麼樣的過濾方法? –

+0

@PanosRontogiannis 1.是的,我加了檢查: 't => {var。attr = t。GetCustomAttribute (); 回報(ATTR == NULL空:attr.Name); }' 但不知道如何取消添加元數據屬性是否存在不2. 我don'n知道如何添加一個元數據,因爲AddMetadata方法需要首先需要參數'串name'。而這個變種'exportBuilder.AddMetadata(空,新PluginMetadataAttribute( 「插件1」, 「1.0.0.0」))'不工作。請告訴我該怎麼做? 3.我想過濾屬性存在的類 – anpv