简体   繁体   English

MEF:无法在其他课程中导入?

[英]MEF: Unable to import in other classes?

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? 现在唯一挥之不去的问题是如何在WPF中执行此操作? I have a custom part based off of a UserControl but there is no way in WPF to do : 我有一个基于UserControl的自定义部件,但WPF无法做到:

[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. 我在项目中遇到[导入]各种MEF组件的问题。 Do I have to use a CompositionContainer in every class I use? 我是否必须在我使用的每个类中使用CompositionContainer? 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. 在下面的代码中,Helper.TimesTwo()方法中抛出了一个空引用异常,但是当我在Program类中调用logger.Log()时,一切正常。 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;
        }
    }
}

I think the trick is to make use of the fact that MEF will cascade its imports. 我认为诀窍是利用MEF将其进口级联的事实。 So if you import your Helper instance rather than declaring it as a local variable, any imports that the Helper requires will be satisfied. 因此,如果您导入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'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. 我确信有一种方法可以满足局部变量中的任何导入,但我喜欢使用像这样的“级联导入”功能。

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 格伦

Try changing 尝试改变

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

to

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

It might work. 它可能会奏效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM