从MEF导入构建类和方法层次结构

时间:2014-02-09 09:34:12

标签: c# .net mef

我正在尝试构建一个使用Managed Entity Framework导入未知数量的类及其相关方法的应用程序。

例如,我有以下两个类:

interface IClass { }

[Export(typeof(IClass))]
class Class1 : IClass
{
    [Export(typeof(Func<int>))]        
    public int GetNumber()
    {
        return 1;
    }
}

[Export(typeof(IClass))]
class Class2 : IClass
{
    [Export(typeof(Func<int>))]
    public int GetNumber1()
    {
        return 1;
    }

    [Export(typeof(Func<int>))]
    public int GetNumber2()
    {
        return 2;
    }
}

Class1有一个GetNumber方法,而Class2有两个。

在我的程序中,我能够创建加载类和方法的导入。

class Program
{   
    [ImportMany]
    IEnumerable<IClass> Classes { get; set; }

    [ImportMany(typeof(Func<int>))]
    IEnumerable<Func<int>> Methods { get; set; }

    static void Main(string[] args)
    {
        Program p = new Program();
        p.Run();
        Console.Read();
    }

    void Run()
    {
        AssemblyCatalog catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
        CompositionContainer container = new CompositionContainer(catalog);

        container.ComposeParts(this);

        if(this.Classes.Count() != 2)
        {
            throw new InvalidOperationException();
        }

        this.Methods.ToList().ForEach(m => Console.WriteLine(m()));
    }
}

输出

  • 1
  • 1
  • 2

我遇到的问题是类和方法之间的链接已丢失。由于所有类和方法都被抛入同一个IEnumerable,我无法分辨哪个类与哪个方法相关联。

我真的想构建一个内存结构,类似于对类和方法的层次结构进行建模,例如

Class1:GetNumber

Class2:GetNumber1,GetNumber2

如何导入这些相同的类和方法,但保留类到方法链接?

1 个答案:

答案 0 :(得分:1)

这可以通过使用container.GetExportedValues来实现,这将公开类和方法。然后可以将它们分组并组成优选结构。实际上你根本不需要[ImportMany]。考虑到MEF意味着为你执行合成,这感觉有点倒退,但它适用于这种情况。

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();
        p.Run();
        Console.Read();
    }

    void Run()
    {
        AssemblyCatalog catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
        CompositionContainer container = new CompositionContainer(catalog);

        Dictionary<IClass, List<Func<int>>> dictionary = new Dictionary<IClass, List<Func<int>>>();

        IEnumerable<IClass> classes = container.GetExportedValues<IClass>();
        IEnumerable<Func<int>> methods = container.GetExportedValues<Func<int>>();

        foreach(var c in classes)
        {
            dictionary[c] = new List<Func<int>>();
        }

        foreach(var m in methods)
        {
            dictionary[(IClass)m.Target].Add(m);
        }            

        foreach(var kvp in dictionary)
        {
            kvp.Value.ForEach(m => Console.WriteLine(m()));
        }
    }
}

如果您需要元数据,请使用container.GetExports