2015-05-24 3 views
1

Я написал общий интерфейс и со временем, я начал использовать его довольно часто. У меня также была идея фактически предоставить еще один общий интерфейс, расширяющий существующий.C#, Unity IoC: Регистрация и разрешение общих интерфейсов, передовая практика

Теперь, когда я смотрю в моем Unity конфигурации (рамки IoC не имеет значения здесь), это выглядит следующим образом:

container.RegisterType<IConfigProvider<ICountryConfig>, CountryConfigProvider>(); 
container.RegisterType<IConfigProvider<ILanguageConfig>, LanguageConfigProvider>(); 

// IEnumerableConfigProvider<T> : IConfigProvider<IEnumerable<T>> 
container.RegisterType<IEnumerableConfigProvider<ILocaleConfig>, LocaleConfigProvider>(); 

// ... repeat gazillion of times... 

Использование в зависимости:

public LocaleResolver(IConfigProvider<ICountryConfig> countryConfigProvider, ...) 
{ 
    // similar construct all over the place 
} 

Где ICountryConfig, ILanguageConfig,. .. являются интерфейсами, описывающими объекты базы данных. Затем поставщик заботится о предоставлении правильных объектов зависимым компонентам, поэтому доступ к хранилищу хранится на собственном месте.

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

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

// ICountryConfigProvider : IConfigProvider<ICountryConfig> 
container.RegisterType<ICountryConfigProvider, CountryConfigProvider>(); 

// ILanguageConfigProvider : IConfigProvider<ILanguageConfig> 
container.RegisterType<ILanguageConfigProvider, LanguageConfigProvider>(); 

// ILocaleConfigProvider : IEnumerableConfigProvider<ILocaleConfig> 
container.RegisterType<ILocaleConfigProvider, LocaleConfigProvider>(); 

И это уборщик использование:

public LocaleResolver(ICountryConfigProvider countryConfigProvider, ...) 
{ 
    // ... 
} 

И то, что я ищу сейчас хороший совет. Может быть, я слишком сильно злоупотребляю IoC здесь. Каков наилучший подход для проекта среднего размера?


Я знаю эту тему, возможно, в конечном итоге с обсуждения, а не конкретный ответ, я извиняюсь за это дорогой StackOverflow.

+0

Вы считали [регистрацию открытых дженериков] (https://msdn.microsoft.com/en-us/library/dn178463 (v = pandp.30) .aspx # sec13)? – TylerOhlsen

+0

Не совсем, не представляю, как это может мне помочь в этом случае. –

ответ

0

Если каждый поставщик отличается от конкретного конкретного типа, то этот подход, хотя и подробный с пустыми интерфейсами, действителен. Другое, менее подробное решение будет обобщать доступ к конфигурации, поэтому вместо этого у вас есть одна конфигурация «service», которая возвращает любую из многих конкретных конфигурационных капли.

Eg configProvider.GetConfig<IWhateverConfig>(); 

Таким образом, вы не заливая контейнер с большим количеством поставщиков для того, что является по существу только поиск определенного типа мешка собственности полных конфигураций. Вы зарегистрировали бы одного поставщика конфигурации и под обложками отображали конфигурационный тип в разделе конфигурации. Если вы выставили эту функцию отображения, тогда конфигурации blobs можно зарегистрировать более модульным способом в любой момент во время запуска приложения.

+0

Мне нравится идея создания родового конфигурационного провайдера, но в моем случае я не смог обобщить его на уровень, я мог бы поместить его в один провайдер (например, моя локальная сущность может фактически отказаться от записи, которая не связана с языком) В любом случае, спасибо для обеспечения меня я не делаю что-то ужасно неправильно :) –

Смежные вопросы