MEF:无法导入其他类?

发布于 2024-07-12 12:31:17 字数 2023 浏览 5 评论 0原文

编辑:马特,这确实解决了我的一些(大多数)问题,谢谢。 现在唯一悬而未决的问题是如何在 WPF 中执行此操作? 我有一个基于 UserControl 的自定义部分,但 WPF 中无法执行此操作:

[Import]<my:SomeCustomControl>

因此级联在此实例中不起作用。

/编辑


我在项目中[导入]各种 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;
        }
    }
}

Edit: Matt, that does indeed solves some (most) of my problems, thank you. Now the only lingering issue of how do I do this in WPF? I have a custom part based off of a UserControl but there is no way in WPF to do :

[Import]<my:SomeCustomControl>

so the cascade doesn't work in this instance.

/Edit


I am having an issue [Import]ing various MEF components in my project. Do I have to use a CompositionContainer in every class I use? In the code below, a null reference exception is thrown in the method Helper.TimesTwo() but when I call logger.Log() in the Program class, everything works. Any help would be greatly appreciated.

(this will compile and run as a console app).

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;
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寄意 2024-07-19 12:31:17

我认为诀窍是利用 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();
    }

我确信有一种方法可以让它满足局部变量中的任何导入,但我喜欢使用这样的“级联导入”功能。

I think the trick is to make use of the fact that MEF will cascade its imports. So if you import your Helper instance rather than declaring it as a local variable, any imports that the Helper requires will be satisfied.

    [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();
    }

I'm sure there's a way to have it satisfy any imports in a local variable, but I like using the "cascaded imports" feature like that.

陈年往事 2024-07-19 12:31:17

不,你不能那样做。 为此,您可以考虑使用附加属性。 通过附加属性,您可以让容器组成添加附加属性的元素。 另一种选择是标记扩展。

格伦

No you can't do that. You could look into using attached properties though for this. With an attached property you can have the container compose the element that the attached property is added to. Another option would be markup extensions.

Glenn

赠佳期 2024-07-19 12:31:17

尝试更改

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

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

它可能会起作用。

Try changing

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

to

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

It might work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文