MEF:使用ExportMetaData属性发现插件

时间:2011-07-15 09:13:29

标签: mef

在下面的代码中,我使用合同ICalculator发现所有插件,然后根据metat数据属性选择插件。

我需要直接发现插件,具体取决于ExportMetadata属性,而不是接口合同类型“ICalculator”。 我有什么方法可以做到吗?

谢谢!

public abstract class MathOperation : ICalculator
{
    public abstract int GetNumber(int num1, int num2);      
}

[Export(typeof(ICalculator))]
[ExportMetadata("CalciMetaData", "Add")]
public class Add : MathOperation
{
    #region Interface members
    public override int GetNumber(int num1, int num2)
    {
        return num1 + num2;
    }
    #endregion
}

[Export(typeof(ICalculator))]
[ExportMetadata("CalciMetaData", "Divide")]
public class Divide : MathOperation
{
    #region Interface members
    public override int GetNumber(int num1, int num2)
    {
        return num1 / num2;
    }
    #endregion
}

// Composition.
public class CalciCompositionHelper
{
    [ImportMany]
    public System.Lazy<ICalculator, IDictionary<string, object>>[] CalciPlugins { get; set; }

    /// <summary>
    /// Assembles the calculator components
    /// </summary>
    public void AssembleCalculatorComponents()
    {
        try
        {
            //Step 1: Initializes a new instance of the 
            //        System.ComponentModel.Composition.Hosting.AssemblyCatalog class with the 
            //        current executing assembly.
            var catalog = new AssemblyCatalog(Assembly.LoadFrom(@"D:\Study\MEF_Program_Files\Files\SimpleCalculator-Part2\CalculatorUI\CalculatorFactory\bin\Debug\CalculatorFactory.dll"));

            //Step 2: The assemblies obtained in step 1 are added to the CompositionContainer
            var container = new CompositionContainer(catalog);

            //Step 3: Composable parts are created here i.e. the Import and Export components 
            //        assembles here
            container.ComposeParts(this);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// Sends the result back to the client
    /// </summary>
    /// <param name="num1"></param>
    /// <param name="num2"></param>
    /// <returns></returns>
    public int GetResult(int num1, int num2, string operationType)
    {
        int result = 0;
        foreach (var CalciPlugin in CalciPlugins)
        {
            if ((string)CalciPlugin.Metadata["CalciMetaData"] == operationType)
            {
                result = CalciPlugin.Value.GetNumber(num1, num2);
                break;
            }                               
        }
        return result;           
    }
}

1 个答案:

答案 0 :(得分:0)

您应该可以使用CompositionContainer.GetExports(ImportDefinition definition)。在ImportDefinition中,您可以设置Constraint属性以匹配您要查找的特定元数据。通常,您需要知道接口类型,否则您将如何与从CompositionContainer获得的值进行交互?