Многие зависимости IoC в процессах типа сценария транзакции - что мы делаем неправильно? - PullRequest
0 голосов
/ 10 сентября 2010

У нас есть много длительных процессов, каждый из которых требует десятков шагов. Каждый шаг сам по себе является относительно сложным, поэтому мы разбили его на свои классы. Мы используем DI / IoC (StructureMap), чтобы помочь нам сделать все это тестируемым. Это прекрасно работает, но мы обнаруживаем кучу зависимостей в наших управляющих классах.

Например, одна из наших больших подпрограмм обрабатывает загрузку файла клиента 401k. Это имеет почти 70 отдельных шагов. Каждая логическая группа шагов имеет свой собственный класс, всего 14. Каждый из них довольно маленький и управляемый, но класс, который организует весь процесс, имеет массу зависимостей (то есть у нас есть группа классов Бога):

    public Client401kProcessor (IValidator uploadValidator, 
        IGeneralLedgerExporter glExporter, 
        IDataMapper dataMapper,
        IFinanceRepository financeRep,
        //...9 more
        IClientFileAuditor auditor)
    {
        _uploadValidator = uploadValidator;
        //... etc
    }

Этот конкретный класс имеет только пару открытых функций, что делает его очень простым в использовании:

    public void ProcessClientFile(Guid savedFileId)
    {
        var clientUpload = _financeRep.FetchClientFile(savedFileId);
        _uploadValidator.Validate(clientUpload);
        _dataMapper.MapToStagedArea(clientUpload);
        _dataMapper.FlagAsStaged(clientUpload.Id);
        //...
        _auditor.RecordChanges(client.Id);
    }

Я чувствую, что мы должны что-то упустить. Тестировать, понимать и писать приведенный выше код довольно просто ... но люди .NET говорят нам, что у нас слишком много зависимостей. Как бы мы сократили эти зависимости и в то же время сделали код легким для тестирования / сопровождения?

1 Ответ

1 голос
/ 10 сентября 2010

Как говорит Арен в своих комментариях, вы можете представить агрегирующую службу - посредника, который заботится о координации набора зависимостей. Первый вопрос, который вы должны задать себе перед тем, как сделать это, - какова ответственность класса со всеми этими зависимостями. На самом ли деле это единственная ответственность?

Прочитайте сообщение Джеффри Палермоса в блоге о запахе кода "Конструктор через инъекцию" и следите за обсуждениями и последующих сообщений , которые это вызвало. Марк Симан опубликовал пару последующих замечаний, в том числе «Рефакторинг для агрегированных услуг» , что хорошо читается в вашем случае.

В вашем конкретном случае метод ProcessClientFile может быть извлечен в класс ClientFileProcessor или пару классов, если обработка файла состоит из нескольких логических шагов с дискретными обязанностями.

...