2010-11-21 2 views
4

건물중인 응용 프로그램의 플러그인 시스템에 MEF를 사용하려고합니다. 각 구성 요소에 대해 조회 할 수있는 식별자 (GUID)가 필요합니다. 그러나이 ID는 내 보낸 파트로 작업 할 때 유용합니다.MEF 내 보낸 부품의 메타 데이터

내 보낸 부분의 ID 또는 속성 (또는 메소드)을 포함하는 메타 데이터 속성을 가질 수있는 방법이 있습니까? 개발자가 속성을 두 번 채우거나 속성에서 찾지 못하게하는 방법이 있습니까? ?

답변

7

MEF 메타 데이터 속성과 추상 기본 클래스가 혼합되어있을 가능성이 큽니다. 나는 IPlugin 인터페이스는 또한 우리의 메타 데이터 계약 IPluginMetadata을 상속 시행 한

public interface IPluginMetadata 
{ 
    Guid PluginId { get; } 
} 

public interface IPlugin : IPluginMetadata 
{ 
    void Initialise(); 
} 

: 내가 좋아하는 무언가로 내 플러그인 계약을 정의하는 것입니다. 다음으로, 우리는 사용자 정의 수출 속성을 만들 수 있습니다 : 당신은 MEF 어쨌든 속성을 투사됩니다로서, 메타 데이터 계약 IPluginMetadata로 반출 속성을 장식 할 필요가 없습니다

[AttributeUsage(AttributeTargets.Class, Inherit = true), MetadataAttribute] 
public class ExportPluginAttribute : ExportAttribute, IPluginMetadata 
{ 
    public ExportPluginAttribute(string pluginId) : base(typeof(IPlugin)) 
    { 
    if (string.IsNullOrEmpty(pluginId)) 
     throw new ArgumentException("'pluginId' is required.", "pluginId"); 

    PluginId = new Guid(pluginId); 
    } 

    public Guid PluginId { get; private set; } 
} 

을,하지만 난 그래서 만약, 그렇게하는 것을 선호 내 메타 데이터 계약에 대한 변경 사항을 소개하고 내 내보내기 속성도 업데이트해야합니다. 아무런 해가 없으며 파울도 없습니다. 우리가이 일을하면

, 우리는 우리의 플러그인 계약 구현에서 추상 기본 클래스를 정의 할 수 있습니다 :

public abstract class PluginBase : IPlugin 
{ 
    protected PluginBase() 
    { 
    var attr = GetType() 
     .GetCustomAttributes(typeof(ExportPluginAttribute), true) 
     .Cast<ExportPluginAttribute>() 
     .SingleOrDefault(); 

    PluginId = (attr == null) ? Guid.Empty : attr.PluginId; 
    } 

    public virtual Guid PluginId { get; private set; } 

    public abstract void Initialise(); 
} 

우리는 다음 정의는 추상 클래스의 생성자를 통해 속성 잡을 수 및 속성을 적용 따라서. 우리가 할 수있는 : 또한

public IPlugin GetPlugin(Guid id) 
{ 
    var plugin = container 
    .GetExports<IPlugin, IPluginMetadata>() 
    .Where(p => p.Metadata.PluginId == id) 
    .Select(p => p.Value) 
    .FirstOrDefault(); 

    return plugin; 
} 

과 :

[ExportPlugin("BE112EA1-1AA1-4B92-934A-9EA8B90D622C")] 
public class MyPlugin : PluginBase 
{ 
    public override Initialise() 
    { 
    Console.WriteLine(PluginId); 
    } 
} 

우리는 PluginId 모두 내 보낸 메타 데이터를 통해 노출되는을 참조뿐만 아니라 우리의 플러그인의 속성 수 있습니다.

그 코드는 모두 테스트되지 않았지만 올바른 방향으로 사용자를 밀어주기를 바랍니다. 그이 허용되지 않는,

[Export(typeof(IFoo))] 
[ExportMetadata("GUID", _guid)] 
public class Foo : IFoo 
{ 
    private const string _guid = "abc"; 

    public string Guid { get { return _guid; } } 
} 

주 대신 stringGuid 유형을 사용할 수 없습니다

+0

+1 멋지고 멋진 아이디어와 구현! –

+1

그게 내가 Guid를 메타 데이터 객체의 속성 유형으로 사용할 수 없다는 것을 지적 할지라도 내가 함께 가야 할 생각이었다. * 거대한 거래가 아니라, CodeContract를 사용하여 속성의 ctor에 적용했습니다. –

0

일정에 GUID를 넣어하고, 등록 정보와 메타 데이터를 모두 사용 const 키워드