2016-10-04 3 views
1

У меня есть два взаимозависимых класса, которые я хочу создать Autofac. В принципе, родитель нуждается в ссылке на ребенка, а ребенку нужна ссылка на услугу, которая в этом случае реализуется родителем.Как создать взаимозависимые компоненты с помощью Autofac

public class Parent : ISomeService 
{ 
    private IChild m_child; 

    public Parent(IChild child) 
    { 
     m_child = child; // problem: need to pass "this" to child constructor 
    } 
} 

public class Child : IChild 
{ 
    public Child(ISomeService someService) 
    { 
     // ...store and/or use the service... 
    } 
} 

Любые идеи?

+0

Вы должны действительно избегать круговой зависимости. В вашем случае одним из решений было бы разделить класс «Parent» в двух разных классах –

+0

@CyrilDurand, можете ли вы подробно рассказать о конкретных проблемах, с которыми вы столкнулись с круговыми зависимостями? Для графиков объектов очень часто встречаются циклы, поэтому их часто бывает трудно избежать. –

+0

Это больше проблем дизайна, чем конкретная техническая проблема. Он часто указывает на проблему с дизайном, которая указывает, что ваши компоненты не являются [твердыми] (https://en.wikipedia.org/wiki/SOLID_ (object-oriented_design)). Обходной путь для введения циклической зависимости также сделает код менее читаемым, а тестовый макет будет более сложным. [Циклическая зависимость от wikipedia] (https://en.wikipedia.org/wiki/Circular_dependency) также обсуждают некоторые проблемы с круговыми зависимостями. Если возможно, попытайтесь избежать зависимостей theses, введя новый компонент и т. Д. –

ответ

0

Я нашел довольно элегантное решение, используя parameterized instantiation. Это позволяет зависимость ребенка от ISomeService быть решена с использованием существующего объекта (Parent экземпляра) без введения каких-либо грязные проблем продолжительности жизни (насколько я могу сказать):

public class Parent : ISomeService 
{ 
    private IChild m_child; 

    public Parent(Func<ISomeService, IChild> childFactory) 
    { 
     m_child = childFactory(this); 
    } 
} 

public class Child : IChild 
{ 
    public Child(ISomeService someService) 
    { 
     // ...store and/or use the service... 
    } 
} 

// Registration looks like this: 

builder.RegisterType<Parent>(); // registered as self, NOT as ISomeService 
builder.RegisterType<Child>().AsImplementedInterfaces(); 

работает как шарм. :)

Смежные вопросы