MEF: обнаружение плагина с использованием атрибута ExportMetaData - PullRequest
0 голосов
/ 15 июля 2011

В приведенном ниже коде я обнаруживаю все плагины, используя контракт 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 голосов
/ 09 августа 2011

Вы должны иметь возможность использовать CompositionContainer.GetExports (определение ImportDefinition) . В ImportDefinition вы можете установить свойство Constraint в соответствии с конкретными метаданными, которые вы ищете. Обычно вам нужно знать тип интерфейса, иначе как вы будете взаимодействовать со значением, полученным из CompositionContainer?

...