2016-05-11 4 views
1

У меня есть a экземпляр A и b экземпляр BDependency Injection вопрос (двунаправленная связь)

a должен иметь возможность вызвать метод b и b затем должен немедленно вызвать метод a если некоторые проверки проходить.

Для достижения этой цели я бы циклической DI

public A(B b) { _b = b; } 
public void CallToB() { _b.Method(); } 
public void Method() { DoSomething(); } 

public B(A a) { _a = a; } 
public void Method() { if (SomeCheck()) _a.Method(); } 

Я знаю, что я мог бы получить Arround это, используя события и пусть b не знать/независим от a. Но это было бы неправильно.

Примечание: Я не видел ответа на этот вопрос, когда двунаправленная связь стала возможной.

+1

И вот почему это лучше избегать циклических зависимостей .. (если используются интерфейсы, то есть нет цикл, установленный между самими реализациями, которые, если они выполняются с помощью IoC или другой инъекции, подключены «снаружи» цикла) – user2864740

+0

Циклические зависимости часто указывают на недостаток дизайна - если у вас есть контроль над этими классами, я предлагаю извлечь любые общие зависимости находятся в 'A' и' B' в третьем классе, так что оба 'A' ​​и' B' зависят от этого класса, а не друг друга. – topher

ответ

2

Вы можете решить эту проблему в зависимости от интерфейсов вместо конкретных типов, а затем использовать впрыск свойств. Вот пример:

public interface IA 
{ 
    void Method(); 
} 

public class A : IA 
{ 
    private readonly IB _b; 
    public A(IB b){_b = b;} 
    //... 
} 

public interface IB 
{ 
    void Method(); 
} 

public class B : IB 
{ 
    private readonly IA _a; 
    public B(IA a){_a = a;} 
    //... 
} 

public class BCycleDependencyBreaker : IB 
{ 
    private IB _b; 

    public IB b 
    { 
     set { _b = value; } 
    } 

    public void Method() 
    { 
     _b.Method(); 
    } 
} 

Вы затем использовать BCycleDependencyBreaker, когда вы сочиняете, как это:

var b_cycle_dependency_breaker = new BCycleDependencyBreaker(); 

//Make a depend on this implementation of b that currently does nothing 
A a = new A(b_cycle_dependency_breaker); 

//Make b depend on a 
B b = new B(a); 

//Now, let the proxy implementation delegate calls to the real b 
b_cycle_dependency_breaker.b = b;