Возникли проблемы при попытке изучить MEF - PullRequest
4 голосов
/ 03 июня 2011

Я пытался научить себя MEF, начиная с этого урока:

http://blogs.msdn.com/b/brada/archive/2008/09/29/simple-introduction-to-composite-applications-with-the-managed-extensions-framework.aspx

Существуют некоторые отличия от того, как MEF работает сейчас, по сравнению с тем, как оно работает в этом руководстве. Одним из отличий является объект CompositionBatch; Тем не менее, я думаю, что понимаю изменения, которые были сделаны.

Единственное отличие, которое я не могу понять, это то, что, хотя в учебнике сказано, что я должен быть в состоянии обрабатывать 0/1 / несколько импортов, изменяя тип возвращаемого свойства, я не могу заставить эту работу работать в практика. Ниже я вставлю код, который дает мне ошибку; Может ли кто-нибудь объяснить мне, почему это не работает и что я должен делать вместо этого?

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

namespace MessinWithMef
{
    class Program
    {
        [Import]
        public IEnumerable<string> Message { get; set; }

        public void Run()
        {
            var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var batch = new CompositionBatch();

            batch.AddPart(this);

            var container = new CompositionContainer(catalog);
            container.Compose(batch);

            foreach (var s in Message)
            {
                Console.WriteLine(s);
            }

            Console.ReadKey();
        }

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

    public class SimpleHello
    {
        [Export]
        public string Message
        {
            get
            {
                return "Hello world!";
            }
        }
    }

    public class ExtraHello
    {
        [Export]
        public string OtherMessage
        {
            get
            {
                return "Hi there!";
            }
        }
    }
}

Вот текст ошибки:

The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "System.Collections.Generic.IEnumerable(System.String)") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "System.Collections.Generic.IEnumerable(System.String)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.

Resulting in: Cannot set import 'MessinWithMef.Program.Message (ContractName="System.Collections.Generic.IEnumerable(System.String)")' on part 'MessinWithMef.Program'.
Element: MessinWithMef.Program.Message (ContractName="System.Collections.Generic.IEnumerable(System.String)") -->  MessinWithMef.Program

1 Ответ

3 голосов
/ 03 июня 2011

Вы должны использовать [ImportMany], если хотите разрешить несколько подходящих экспортов.

Обратите внимание, что в сценарии типа плагина вы, вероятно, захотите использовать ExportMetadata, а затем решить, какой из плагинов вы хотите создать. Затем вы должны сделать что-то вроде:

[ImportMany]
IEnumerable<Lazy<IPlugin, IPluginMetadata>> _possiblePlugins;

Теперь ваш код может перечислять возможные плагины, изучать метаданные, а затем решать, создавать ли экземпляры для каждого Lazy-импорта.

...