如何设置具有多个值的ExportMetaData以及单个w / custom属性?

时间:2011-01-10 20:22:59

标签: c# interface mef

我在我的类上设置了以下ExportMetaData属性:

  [Export(typeof(IDocumentViewer))]
  [ExportMetadata("Name", "MyViewer")]
  [ExportMetadata("SupportsEditing", true)]
  [ExportMetadata("Formats", DocFormat.DOC, IsMultiple = true)]
  [ExportMetadata("Formats", DocFormat.DOCX, IsMultiple = true)]
  [ExportMetadata("Formats", DocFormat.RTF, IsMultiple = true)]  

我也有一个支持界面:

  public interface IDocumentViewerMetaData {
    /// <summary>
    /// Gets the format.
    /// </summary>
    /// <value>The format.</value>
    IEnumerable<DocFormat> Formats { get; }
    /// <summary>
    /// Gets the name of the viewer
    /// </summary>
    /// <value>The name.</value>
    string Name { get; }
    /// <summary>
    /// Gets a value indicating whether this viewer supports editing
    /// </summary>
    /// <value><c>true</c> if [supports editing]; otherwise, <c>false</c>.</value>
    bool SupportsEditing { get; }
  }

当然我的ImportMany:

[ImportMany(typeof(IDocumentViewer))]
public IEnumerable<Lazy<IDocumentViewer, IDocumentViewerMetaData>> _viewers { get; set; }

我想要做的是使用强类型属性类而不是使用ExportMetaData属性。我还没有找到一种方法来实现这一点,同时也支持单个值(在上面的例子中,Name,SupportsEditing)。

我设想做一些类似下面的事情(或者建议最好的事情):

[Export(typeof(IDocumentViewer))]
[DocumentViewerMetadata(Name = "MyViewer")]
[DocumentViewerMetadata(SupportsEditing = true)]
[DocumentViewerMetadata(Format = DocFormat.DOC)]
[DocumentViewerMetadata(Format = DocFormat.DOCX)]

我相当确定有一种方法可以做到这一点,我还没有找到正确的方法来连接点。 :)

1 个答案:

答案 0 :(得分:18)

您可以使用您自己的实现继承ExportAttribute,并使用MetadataAttribute对其进行修饰,以允许MEF使用其属性来投影在合成期间使用的元数据代理:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property),
 MetadataAttribute]
public class ExportDocumentViewerAttribute : ExportAttribute, IDocumentViewerMetadata
{
  public ExportDocumentViewer(string name, bool supportsEditing, params DocFormat[] formats)
    : base(typeof(IDocumentViewer))
  {
    if (string.IsNullOrEmpty(name))
      throw new ArgumentException("Export requires a name", "name");

    Name = name;
    SupportsEditing = supportsEditing;
    Formats = formats ?? Enumerable.Empty<DocFormat>();
  }

  public string Name { get; private set; }

  public bool SupportsEditing { get; private set; }

  public IEnumerable<DocFormat> Formats { get; private set; }
}

[ExportDocumentViewer("Word", true, DocFormat.DOC, DocFormat.DOCX)]
public WordDocumentViewer : IDocumentViewer
{
  // Stuff
}

注意您实际上并不需要使用IDocumentViewerMetadata合约来装饰它,因为MEF会投影它,我只是喜欢这样我知道我是否更改了元数据合约,我的自定义导出属性符合。