Рассмотрим следующий пример кода, который использует MEF для создания объекта типа Importer
, который импортирует объект типа ImporterExporter
, который, в свою очередь, импортирует объект типа Exporter
, то есть Importer -> ImporterExporter -> Exporter
.Управление каталогом осуществляется с помощью CompositionUtility
(очевидно, упрощенного для этого примера).
Я знаю, что MEF рекурсивно разрешит импорт импортируемых деталей.Однако, поскольку я хочу иметь возможность создавать экземпляры каждого из этих классов независимо, каждый класс с импортом также создает себя в своем конструкторе для разрешения этих импортов.
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
namespace MefRecursionSample
{
class Program
{
static void Main(string[] args)
{
// var importerExporter = new ImporterExporter(); // include this and composition will work
var importer = new Importer();
Console.Write(importer.ImporterExporter.Exporter.Value); // should print 7
Console.ReadKey();
}
}
class CompositionUtility
{
static CompositionUtility()
{
var executingAssembly = Assembly.GetExecutingAssembly();
var assemblyCatalog = new AssemblyCatalog(executingAssembly);
_compositionContainer = new CompositionContainer(assemblyCatalog);
}
private static CompositionContainer _compositionContainer;
private static bool _isComposing;
public static void Compose(object part)
{
_compositionContainer.ComposeParts(part);
}
}
class Importer
{
public Importer()
{
CompositionUtility.Compose(this);
}
[Import]
public ImporterExporter ImporterExporter { get; set; }
}
[Export]
class ImporterExporter
{
public ImporterExporter()
{
CompositionUtility.Compose(this);
}
[Import]
public Exporter Exporter { get; set; }
}
[Export]
class Exporter
{
public int Value { get { return 7; } }
}
}
Запуск кода как есть приводит к композицииошибка "ComposablePart типа MefRecursionSample.Importer 'не может быть перекомпонована ....", очевидно, потому что я пытаюсь явно составить что-то, что MEF также хочет составить.Я включил первую строку метода Main
, т.е. создал объект типа ImporterExporter
без MEF, эта «двойная композиция» больше не вызывала исключения.Почему это так?
Кроме того, как я мог заставить его работать так, чтобы я мог создавать каждый из них независимо, но также заставлять их составлять себя, когда они связаны, как в образце.Я подумал, что введу логический флаг _compositionInProgress
на CompositionUtility
и сразу же вернусь с Compose()
, когда флаг установлен, чтобы избежать рекурсивной композиции.Есть ли лучший способ?