DI и громоздкая инициализация
От: Larian  
Дата: 30.07.09 20:08
Оценка:
у меня сразу 2 вопроса
1.Вот к примеру понадобилось нам разработать какое-нибудь приложение. Пусть будет программа, которая лезет куда то на сервер, получает ответ, разбирает и выводит сообщение.

И вот начинаем строить его с самого верха. Кинули форму, сделали на ней кнопку "старт" и сделали реализацию MVP.
порядок работы такой
а) нажали на кнопку
б) форма вызвала презентер
в) презентер вызвал форму (заблокировать кнопку)

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

Есть пара вариантов решения
ServiceLocator как контекст (чтобы не пихать по объекту, а одним затолкать много) тут не поможет. Нельзя же все пихать в контекст. Если все пихать, то в итоге получится, что каждый класс, который вызывает уровень ниже, должен создать свой контекст. Тут я упрощаю, но сути это не меняет. Что пихать в локаторы — очень тонкий вопрос.

IoC контейнер- прописать все зависимости где то вначале и при создании таких объектов в презентере не нужно будет так много писать руками (хотя оно уже прописано нашими же руками в конфигурации IoСконтейнере). Но что делать, если сборка таких объектов зависит не от конфига хмл (Спринг) или от того, как закодили (Unity), а от того, какие опции выбрал юзер, прежде чем нажать старт. То есть с ума можно сойти, пока все зависимости возможные закодишь.

Что тут делать? Может в консерватории (архитектуре) подправить? Ткните плиз, где можно скачать и глянуть исходники WinForms/WPF приложений с показательным кодом.

2. нужно использовать парсеры внутри Executorа. Можно,конечно, сделать так
Такой класс можно передать как инъекцию или еще как по интерфейсу.
    class ParserResult
    {
        public string Data1;

        public string Data2;
    }

    class Parser: IParser
    {
        public ParserResult Parse(string text)
        {
            var result = new ParserResult();
            //...тут парсим
            return result;
        }
    }


Но ведь удобнее так.

   class Parser
    {
        private string _text;

        public Parser(string text)
        {
            _text = text;
        }

        public string GetData1()
        {
            return ...
        }

        public string GetData2()
        {
            return ...
        }
    }

то есть передавать парметр в конструктор. Такой класс уже извне не подбросишь. И вариантов вижу 3
1. Отказаться от таких классов. Хотя вроде бы верно, когда состояние объекта устанавливается после отработки конструктора
2. передавать, но добавить возможность задания параметра через сеттер на месте.
3. Передавать фабрику для создания таких обьектов. Но поначалу (а то и навсегда это один объект и неохота еще класс делать только для совместимости)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.