MEF:无法在其他类中导入?

3

编辑:Matt,这确实解决了我大部分问题,谢谢。现在唯一的问题是如何在WPF中实现这个?我有一个基于UserControl的自定义部件,但在WPF中没有办法执行:

[Import]<my:SomeCustomControl>

所以在这种情况下,级联不起作用。

/编辑


我在我的项目中[Import]导入各种MEF组件时遇到了问题。我是否必须在每个使用的类中使用CompositionContainer? 在下面的代码中,在方法Helper.TimesTwo()中抛出了空引用异常,但当我在Program类中调用logger.Log()时,一切正常。非常感谢任何帮助。

(这将编译并运行为控制台应用程序)。

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var p = new Program();
            p.Run();
        }

        [Import]
        private ILog logger { get; set; }

        public void Run()
        {
            var catalog = new DirectoryCatalog(".");
            var container = new CompositionContainer(catalog);
            var batch = new CompositionBatch();
            batch.AddPart(this);
            container.Compose(batch);

            logger.Log("hello");
            var h = new Helper();
            logger.Log(h.TimesTwo(15).ToString());
            Console.ReadKey();
        }
    }

    class Helper
    {
        [Import]
        private IDouble doubler { get; set; }

        private Helper()
        {
            // do I have to do all the work with CompositionContainer here again?
        }

        public double TimesTwo(double d)
        {
            return doubler.DoubleIt(d);
        }
    }

    interface ILog
    {
        void Log(string message);
    }

    [Export(typeof(ILog))]
    class MyLog : ILog
    {
        public void Log(string message)
        {
            Console.WriteLine("mylog: " + message);
        }
    }

    interface IDouble
    {
        double DoubleIt(double d);
    }

    [Export(typeof(IDouble))]
    class MyDoubler : IDouble
    {
        public double DoubleIt(double d)
        {
            return d * 2.0;
        }
    }
}
3个回答

4

我认为诀窍在于利用MEF会级联其导入的事实。因此,如果您导入Helper实例而不是声明它作为局部变量,则将满足Helper所需的任何导入。

    [Import]
    public Helper MyHelper { get; set; }

    public void Run()
    {
        var catalog = new DirectoryCatalog(".");
        var container = new CompositionContainer(catalog);
        var batch = new CompositionBatch();
        batch.AddPart(this);
        container.Compose(batch);
        logger.Log("hello");
        logger.Log(MyHelper.TimesTwo(15).ToString());
        Console.ReadKey();
    }

我相信有一种方法可以将所有导入项满足到本地变量中,但我喜欢使用类似于“级联导入”功能的方式。


1

尝试更改

[Import]        
private ILog logger { get; set; }

[Import]        
public ILog logger { get; set; }

可能会起作用。


1

不,你不能这样做。不过你可以考虑使用附加属性来实现。使用附加属性,你可以让容器组合添加了附加属性的元素。另一个选择是使用标记扩展。

Glenn


我想知道你是否看到了这个,格伦,考虑到你最近关于MEF+WPF的推文。 :) - Matt Hamilton
我有同样的问题,就是在除了MainWindow之外的类中无法[导入]...但这里的答案似乎是针对其他问题的答案? - TimothyP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接