MEF Пользовательские атрибуты и Lazy - PullRequest
1 голос
/ 17 января 2011

Я думаю, что схожу с ума.:) Я боролся с этим уже два дня.Код выглядит правильно.Но по какой-то причине, когда я пытаюсь получить доступ к полю [ImportMany], оно пустое или, по крайней мере, не возвращает никаких значений.

Это получает 3 части в каталоге, но они не применяются к определению Lazy [], которое я определяю.

Вот мой код:

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

namespace MefTest
{

// Extension interface and metadata

    public interface IUIExtension
    {
       void DoSomething();
    }

    public interface IUIExtensionDetails
    {
        string Name { get; }
        string Uri { get; }
    }

    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
    public class UIExtensionAttribute : ExportAttribute
    {
        public UIExtensionAttribute() : base(typeof(IUIExtensionDetails)) { }

        public string Name { get; set; }
        public string Uri { get; set; }
    }

        // Extensions

    [UIExtension(Name="Test 01", Uri="http://www.yourmomma.com/")]
    public class Test1Extension : IUIExtension
    {
        public void DoSomething() { }
    }

    [UIExtension(Name = "Test 02", Uri = "http://www.yourdaddy.com/")]
    public class Test2Extension : IUIExtension
    {
        public void DoSomething() { }
    }

    [UIExtension(Name = "Test 03", Uri = "http://www.youruncle.com/")]
    public class Test3Extension : IUIExtension
    {
        public void DoSomething() { }
    }

        // Main program

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

        [ImportMany]
        public Lazy<IUIExtension, IUIExtensionDetails>[] Senders { get; set; }

        public void Run()
        {
            Compose();
        }

        public void Compose()
        {
            var catalog =  new AssemblyCatalog(
                System.Reflection.Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(catalog);

            container.ComposeParts(this);

            // This is always 3
            Console.WriteLine(
                (from g in container.Catalog.Parts select g).Count());
            // This is always 0
            Console.WriteLine(Senders.Length);

            Console.ReadKey();
        }
    }

}

Ответы [ 2 ]

3 голосов
/ 17 января 2011

Ваша ошибка здесь:

public UIExtensionAttribute() : base(typeof(IUIExtensionDetails))

Вы должны передать тип контракта, а не тип метаданных:

public UIExtensionAttribute() : base(typeof(IUIExtension))

(Кроме того, чтобы убедиться, что ваш пользовательский класс экспорта имеет правильные свойства, как ожидается при импорте с метаданными, я бы заставил его реализовать интерфейс IUIExtensionDetails. Но это не обязательно.)

2 голосов
/ 17 января 2011

Ваш атрибут метаданных определяет экспорт как typeof(IUIExtensionDetails), который является вашим контрактом метаданных, а не фактическим расширением. Измените конструктор пользовательских атрибутов на:

public UIExtensionAttribute() : base(typeof(IUIExtension)) { }
...