2012-03-17 2 views
3

Предположим, у нас есть две компоненты в зависимости друг от друга (опосредованно, через интерфейсы):MEF циклическая зависимость

public interface IAlice { ... } 
public interface IBob { ... } 

[Export(typeof(IAlice)), PartCreationPolicy(CreationPolicy.NonShared)] 
class Alice : IAlice 
{ 
    [Import] 
    private IBob Bob { get; set; } 
    ... 
} 

// could be defined in some assembly developed by another team 
[Export(typeof(IBob)), PartCreationPolicy(CreationPolicy.NonShared)] 
class Bob : IBob 
{ 
    [Import] 
    private IAlice Alice { get; set; } 
    ... 
} 

Это приводит к провалу композиции: Композиция не удалась, поскольку она не была завершена в «100» итераций. Это, скорее всего, вызвано циклом в графике зависимости части, которая отмечена политикой не общего доступа.

Я знаю, что могу импортировать через ленивую декларацию, но таким образом импорт будет создан по требованию, в то время как мне нужно, чтобы мои ссылки Алисы Боб и Боб ссылались на тот же экземпляр Алисы. Я ожидал, что CompositionContainer разрешит такие циклы в рамках одной композиции, но, видимо, это не так.

Я не могу объявить детали как общие, так как мне не нужна единая Алиса и Боб на контейнер. Мне просто нужно, чтобы такие графики зависимостей создавались как единое целое, когда оно выполнялось в одной операции композиции. Есть ли обходной путь?

UPD. Добавлено некоторое уточнение.

+0

Вы упомянули в комментарии к моему ответу, что Алиса и Боб могут быть разработаны различными сторонами. Если это так, то ни Алиса, ни Боб не знают, что существует круговая зависимость, поэтому нельзя ожидать, что оба они относятся к одному и тому же экземпляру. Это говорит о приемлемости ленивого подхода. Что мне не хватает? – Akash

+0

Да, вы правы, ленивый подход приемлем. Я бы предпочел разрешить как ленивый, так и не ленивый импорт, но похоже, что MEF не может обрабатывать нелазные круговые ссылки, в которых участвуют не общие части. Таким образом, мы ограничим все вложения свойств ленивыми. Спасибо за вашу помощь! – yallie

ответ

3

Почему нет Алисы импортировать IBob через инъекцию ctor, а затем явно установить свойство Алисы Боба (т. Е. Боб должен не использовать инъекцию свойств для Алисы)?

+0

(Я не должен был объявлять эти свойства впрыска публичными, извините - исправлен). Дело в том, что Алиса и Боб разрабатываются разными людьми. Алиса не знает, что Боб использует ее, и Боб не знает, что она используется Алисой. Мы не разрешаем инъекции ctor, потому что это может привести к ситуации, когда эта круговая зависимость не может быть решена в принципе, поэтому мы застреваем с введением свойств. – yallie

+0

_Somebody_ должен понимать круговую зависимость. Повторите переопределение свойств, но удалите атрибут Import. Теперь определите «Charlie (IAlice alice, IBob bob) {alice.Bob = bob; bob.Alice = alice; } '. Дайте Charlie публичные свойства для Алисы и Боба и убедитесь, что другие только получают доступ к Алисе или Бобу через эти свойства. – Akash

+0

Спасибо @Akash за ваши предложения, но мы просто не можем так поступать. В нашем случае Алиса и Боб могут быть плагинами, разработанными разными сторонами. И мы не знаем никаких подробностей их реализации. * Кто-то должен понимать круговую зависимость. * - Я надеялся, что этот «Кто-то» может быть MEF. Только MEF обладает полными знаниями обо всех внутренних зависимостях между компонентами. – yallie