Свойство MEF, всегда возвращающее ноль - PullRequest
3 голосов
/ 04 мая 2011

Исходный код

В моем файле BusinessObjects.dll есть простой бизнес-объект:

namespace BusinessObjects
{
    public class MyClass
    {
        public MyClass()
        {
            DateTime = DateTime.Now;
        }

        public DateTime DateTime { get; set; }
    }
}

В моем SharedUI.dll естьполучил этот класс «Context-provider», который я использую для хранения ссылки на текущий выбранный MyClass - помните, что это просто пример:) ...

namespace SharedUI
{
    public class AppContext
    {
        [Export]
        public MyClass SelectedMyClass { get; private set; }

        public void SetupContext(MyClass myClass)
        {
            SelectedMyClass = myClass;
        }

        public static AppContext Context
        {
            get
            {
                if (context == null)
                {
                    context = new AppContext();
                }
                return context;
            }
        }

        private static AppContext context;
    }
}

Мой MefTest.exe имеет этот класс:

namespace MefTest
{
    public class Program
    {
        [Import]
        public MyClass MyClass { get; set; }

        private void Compose()
        {
            var ventSystem = new MyClass();
            AppContext.Context.SetupContext(ventSystem);

            var executingAssembly = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var contextAssembly = new AssemblyCatalog(Assembly.LoadFile(string.Format(@"{0}\SharedUI.dll", Environment.CurrentDirectory)));
            var catalog = new AggregateCatalog(executingAssembly, contextAssembly);

            var container = new CompositionContainer(catalog);

            container.ComposeParts(this);
        }

        private void Run()
        {
            Compose();

            // MyClass is always null in the next line?
            Console.WriteLine(MyClass.DateTime.ToString());

            Console.ReadKey();
        }

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

Я новичок в MEF, поэтому, пожалуйста, потерпите меня:)

ОБНОВЛЕНО Исходный код с советами Дэниела Плейстеда

MyClass sourceто же самое ...

SharedUI.dll теперь выглядит так:

namespace SharedUI
{
    [Export]
    public class AppContext
    {
        [Export(typeof(MyClass))]
        public MyClass SelectedMyClass { get; private set; }

        public void SetupContext(MyClass myClass)
        {
            SelectedMyClass = myClass;
        }
    }
}

MefTest.exe теперь выглядит так:

namespace MefTest
{
    public class Program
    {
        [Import]
        public MyClass MyClass { get; set; }

        [Import]
        public AppContext AppContext { get; set; }

        private void Compose()
        {
            var executingAssembly = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var contextAssembly = new AssemblyCatalog(Assembly.LoadFile(string.Format(@"{0}\SharedUI.dll", Environment.CurrentDirectory)));
            var catalog = new AggregateCatalog(executingAssembly, contextAssembly);

            var container = new CompositionContainer(catalog);

            container.ComposeParts(this);

            var myClass = new MyClass();
            AppContext.SetupContext(myClass);
        }

        private void Run()
        {
            Compose();

            // AppContext.SelectedMyClass is NOT null in the next line... which is good I guess :)
            Console.WriteLine(AppContext.SelectedMyClass.DateTime.ToString());

            // MyClass is always null in the next line?
            Console.WriteLine(MyClass.DateTime.ToString());

            Console.ReadKey();
        }

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

Что я делаюнеправильно, так как я не могу заставить его работать?

Ответы [ 3 ]

2 голосов
/ 06 мая 2011

Когда MEF необходимо получить Export, который находится в свойстве класса, он создаст экземпляр класса и вызовет метод получения свойства.Таким образом, MEF создает новый экземпляр вашего AppContext, отличный от статического экземпляра AppContext.Context.Созданный экземпляр MEF не имеет установленного свойства SelectedMyClass, поэтому импорт завершается нулевым.

1 голос
/ 05 мая 2011

Проблема:

    [Import]        public MyClass MyClass { get; set; }

Для MyClass не определены значения [Экспорт].MEF будет составлять это приложение на основе того, что он «знает», и поскольку он не знает «MyClass» ...

Я заметил это:

    [Export]        public MyClass SelectedMyClass { get; private set; }

Это означает, что вы пытаетесьчтобы обмануть MEF в обновлении одной из его частей время от времени?Решением этой проблемы будет создание пользовательского каталога, который содержит объекты «времени выполнения», в которых вы можете обновлять экспортированное значение для MyClass в любое время.Текущая реализация никогда не разрешит MyClass ...

[edited:] Вы также можете украсить член, но вам придется добавить туда тип класса.Так что это будет работать:

[Export (typeof (MyClass)] public MyClass SelectedMyClass {get; private set;}

0 голосов
/ 04 мая 2011

Вы поставили свой атрибут Export в неправильном месте.

Вы должны поместить его в определение MyClass примерно так:

namespace BusinessObjects
{
[Export]
public class MyClass
{
    public MyClass()
    {
        DateTime = DateTime.Now;
    }

    public DateTime DateTime { get; set; }
}
}

И затем использовать [Import], где бы вы ни находились, экземпляр этого класса.

Примечание: Вы не можете использовать MEF для перемещения определенного экземпляра класса (не так).MEF используется для создания экземпляров запрошенного типа и внедрения их в указанные места.

Чтобы узнать больше о MEF, посетите страницу проекта по адресу CodePlex .

...