MEF: Невозможно импортировать в другие классы? - PullRequest
3 голосов
/ 01 февраля 2009

Редактировать: Мэтт, это действительно решает некоторые (большинство) из моих проблем, спасибо. Теперь единственная давняя проблема, как мне сделать это в WPF? У меня есть пользовательская часть, основанная на UserControl, но в WPF нет способа сделать:

[Import]<my:SomeCustomControl>

так что каскад не работает в этом случае.

/ Edit


У меня возникла проблема [Импорт] различных компонентов MEF в моем проекте. Должен ли я использовать CompositionContainer в каждом используемом классе? В приведенном ниже коде исключение нулевой ссылки вызывается в методе Helper.TimesTwo (), но когда я вызываю logger.Log () в классе Program, все работает Любая помощь будет принята с благодарностью.

(это будет скомпилировано и запущено как консольное приложение).

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 голосов
/ 01 февраля 2009

Я думаю, что хитрость заключается в том, чтобы использовать тот факт, что MEF будет каскадно импортировать. Поэтому, если вы импортируете свой экземпляр Помощника, а не объявляете его как локальную переменную, любой импорт, который требуется Помощнику, будет удовлетворен.

    [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 голос
/ 15 июня 2011

Попробуйте изменить

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

до

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

Это может сработать.

1 голос
/ 01 февраля 2009

Нет, ты не можешь этого сделать. Вы можете посмотреть на использование прикрепленных свойств, хотя для этого. С прикрепленным свойством вы можете сделать так, чтобы контейнер составлял элемент, к которому добавлено присоединенное свойство. Другим вариантом будет расширение разметки.

Гленн

...