#c_sharp #net #dependency_injection
Взялся я за реализацию IoC для сервиса данных. Сделал вот так: interface IDataService { } и его реализация (возьмем для примера RpcJson): class JsonRpcDataService : IDataService { } Далее регистрируем их в IoC-контейнере. Тут все пока понятно. Далее переходим к собственно к реализации. Я определил следующую структуру сервиса данных: Модели - тут все понятно Коллекторы - это вспомогательные классы для получения данных Обработчики - вспомогательные классы для обработки данных (сохранения, например) Опишем интерфейс модели: interface IBook { string Autor { get; set; } ... } Коллектор: interface IBooksCollector { IEnumerableGetItems(); ... } И обработчик: interface IBooksHandler { void Save(IBook book); ... } Ну и, соответственно, для реализуем каждый из них для JsonRpc. Далее дополняем интерфейс IDataService: interface IDataService { IBook CreateBook(); IBooksCollector CreateBooksCollector(); IBooksHandler CreateBooksHandler(); } И реализуем эти методы в JsonRpcDataService. Их я сделал для того, чтобы я на уровне ViewModel должен был бы связывать только IDataService с RpcJsonDataService, а не все интерфейсы с их реализациями. Чтобы в итоге я мог делать как-то так: var dataService = IoC.Resolve (); // Создаем модель IBook book = dataService.CreateBook(); Вместо IBook book = IoC.Resolve (); и где-то до этого связывание IBook book = IoC.Register (); где Book - реализация IBook для RpcJson. Так как моделей может быть очень много, то вместо кучи строк вида: IoC.Register (); Все сводится к одной: IoC.Register (); По ходу у меня появились вопросы, на которые я и прошу Вас ответить: Правилен ли такой подход с созданием инстансов? Или может сделать фабрики вида CreateModel (), в которую в качестве параметра T будет передаваться интерфейс, а фабрика уже будет решать что "отдать"? Стоит ли вообще делать интерфейсы для моделей, или лучше описать их сразу? Выделил я их для того, чтобы не загромождать из атрибутами вида [JsonProperty(...)], необходимые для сериализации, ведь эти атрибуты нужны только для сервера RpcJson
Ответы
Ответ 1
В первую очередь - неверно ваше желание обойтись минимальным количеством регистраций компонентов. Если у вас 40 компонентов нет ничего зазорного в том чтобы регистрировать все 40 компонентов в контейнере. Это не будет ошибкой. Более того, хотя многие контейнеры и поддерживают в том или ином виде автоматическую регистрацию компонентов, Castle Windsor например, насколько мне известно, обязывает вас явно регистрировать каждый компонент, и такой подход с явной регистрацией имеет определенный смысл. Но здесь вы вправе выбрать то что вам ближе - автоматическая регистрация или явная регистрация каждого компонента, оба подхода имеют свои преимущества и недостатки. Второе - вы ошибочно ассоциируете регистрацию компонента и последующее получение его из контейнера. Если вы написали IoC.Register(); это не означает что потом для получения IComponent вы обязаны получать его из контейнера. Как правило, вы регистрируете n - компонентов, но из IoC контейнера - запрашиваете только один. Например, если у вас ASP-MVC приложение, в нем может быть много компонентов (контроллеры, сервисы и т.д.), но запрос компонента из IoC контейнера у вас будет всего один - это будет запрос контроллера в фабрике контроллеров. Чтобы понять зачем регистрировать 10 компонентов, если запрашиваться будет только 1 читайте про основные паттерны внедрения зависимостей - внедрение конструктора и внедрение свойства. Ответы на ваши вопросы: Использование фабрик для создания моделей - нормальный подход. Создавать фабричный метод вида CreateModel () где T интерфейс модели, не имеет смысла. Подумайте, чем этот метод будет принципиально отличаться от аналогичного метода IoC-контейнера? Скорее всего не стоит делать интерфейсы для моделей. Использование IoC контейнера вовсе не обязывает вас делать интерфейсы для каждого класса в вашем приложении. Для моделей интерфейсы чаще всего не нужны. По формулировке вашего вопроса видно что вы довольно плохо ориентируетесь в теме и двигаетесь в неверном направлении. Вам стоит потратить немного времени на ее изучение, прежде чем проектировать приложение. В частности паттерны внедрения зависимостей, упомянутые выше (внедрение конструктора и внедрение свойства), существенно важнее для понимания DI, чем любые вопросы, связанные с регистрацией компонентов в IoC-контейнере. Вообще внедрение зависимостей это как раз про эти паттерны, а IoC-контейнер это просто инструмент, облегчающий построение приложения с использованием DI, и DI можно применять вообще без IoC-контейнера. В комменатриях @cybrex посоветовал прочитать книгу Симан М. - Внедрение зависимостей в .NET. Я присоденияюсь к этому совету, почитайте - не пожалеете.
Комментариев нет:
Отправить комментарий