разрешение круговых зависимостей с [закрытым] внедрением зависимости

Альтернативный способ сделать это должно создать обертку вокруг SmtpClient, который реализует тот же интерфейс. Затем введите и используйте обертку в своем классе. При выполнении поблочного тестирования можно затем заменить ложной оберткой, которая имеет ожидания вызовов метода и ответов.

РЕДАКТИРОВАНИЕ : обертка необходима (для RhinoMocks, по крайней мере), потому что SmtpClient не происходит из интерфейса и не имеет виртуальных методов. При использовании платформы насмешки, которая может дразнить класс без виртуальных методов непосредственно, можно пропустить обертку и ввести насмешку SmtpClient непосредственно.

public class SmtpClientWrapper
{
    private SmtpClient Client { get; set; }

    public SmtpClientWrapper( SmtpClient client )
    {
         this.Client = client;
    }

    public virtual void Send( MailMessage msg )
    {
         this.Client.Send( msg );
    }

    ...
}


public class MyClass
{
    private SmtpClientWrapper Client { get; set; }

    public MyClass( SmtpClientWrapper client )
    {
         this.Client = client;
    }

    public void DoSomethingAndNotify()
    {
         ...
         this.Client.Send( msg );
    }
}

Протестированный (с RhinoMocks) как:

public void DoSomethingAndNotifySendsAMessageTest()
{
     SmtpClientWrapper client = MockRepository.GenerateMock<SmtpClientWrapper>();
     client.Expect( c => c.Send( new MailMessage() ) ).IgnoreArguments();

     MyClass klass = new MyClass( client );

     klass.DoSomethingAndNotify();

     client.VerifyAllExpectations();
}
11
задан Jon Seigel 18 May 2010 в 03:01
поделиться

3 ответа

Если у вас есть круговые зависимости между двумя объектами, это означает, что вам нужен третий объект, от которого будут зависеть два объекта, поэтому они не будут зависеть от друг с другом. Вот статья, которая является точным решением вашей проблемы:

http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/

31
ответ дан 3 December 2019 в 01:16
поделиться

DI предназначен не для разрешения циклических зависимостей, а для облегчения создания хорошо разделенных компонентов и, следовательно, более тестируемых.

3
ответ дан 3 December 2019 в 01:16
поделиться
  1. Да, вы усложняете их обнаружение, используя дополнительный уровень абстракции.
  2. Вы абсолютно не решаете циклическую зависимость, а скрываете ее, добавляя дополнительный уровень абстракции, используя позднее ограничение или / и слабо связывая его.

Тот же ответ возвращается в следующих сообщениях (которые я добавлю для справок), которые создают третий класс, от которого оба зависят . Это означает: вы нарушаете принцип единой ответственности . Перемещая (извлекая) ответственность, от которой оба класса зависят, в отдельный класс, вы удалите циклическую зависимость.

К вашему сведению, шаблон единой ответственности в Википедии

Обсуждения StackOverflow другими:

Мой ответ на StackOverflow с примером выделения ответственности в отдельном классе.

8
ответ дан 3 December 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: