2014-01-05 4 views
2

У меня есть небольшое приложение (Win Forms), где у меня есть два разных хранилища (SQL Server и Redis), реализующие интерфейс IFilterRepo. У меня также есть класс обслуживания, который зависит от IFilterRepo. Клиент (Win Form) вызывает службу для доступа к данным фильтра.Unity - используйте конкретный тип в зависимости от выбора пользователя

Я хочу, чтобы у клиента было два переключателя, в которых пользователь может выбрать, какой репо использовать. И вот моя дилемма. Как я должен сообщить службе, которую конкретный класс должен создать как IFilterRepo? Я имею в виду, что все записи Unity и ссылки на него должны выполняться в корне композиции. Это «правило» действительно возможно в этом случае?

ответ

1

Это распространенный вопрос, и ответ, как правило, используется абстрактной фабрикой.

Вот хорошая статья на эту тему (я связываю это все время, но я не писал):

http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/

Как отмечается в статье, вы можете сделать заводскую часть из корня композиции, так что вызов container.Resolve() внутри фабрики не нарушает это правило.

Редактировать

Вы бы зарегистрировать различные реализации сервиса, используя имя (строка):

http://msdn.microsoft.com/en-us/library/ff648211.aspx

myContainer.RegisterType<IMyService, CustomerService>("Customers"); 

И тогда ваша фабрика будет решить с этим именем:

public IFilterRepo Create(string myName) 
{ 
    return myContainer.Resolve<IFilterRepo>(myName); 
} 

Edit 2

Вопрос, который вы просили в своем последнем комментарии многовато ответить здесь, но вкратце: сама ваша фабрика будет реализовать интерфейс, и будет решена и зарегистрированы с помощью контейнера.

Как правило, я бы не рекомендовал обращаться к репозиторию непосредственно из кода позади - я бы по крайней мере посмотрел на наличие многоуровневой архитектуры (или, лучше, архитектуры Onion, которая очень хорошо работает с DI).

Наконец, я не делал разработку WinForms в течение многих лет, но я не думаю, что она идеально подходит для использования контейнера/состава Root, поскольку у вас нет полного контроля над жизненным циклом ваших объектов (вы можете " t вводить сервисы в конструкторы форм). То же самое относится к ASP.Net Webforms. Таким образом, вам может потребоваться использовать вложение свойств для ваших заводских и других услуг, необходимых в вашей форме, или просто разрешить фабрику напрямую, вызвав статический экземпляр контейнера (container.Resolve()). Это несовершенно, и идет вразрез с идеей создания Корзины Композиции и больше в отношении местоположения службы.

Вы можете использовать ключевые слова google «Unity WinForms» и/или «[OtherDIFramework] Winforms», чтобы получить представление о том, как структурировать ваш код.

+0

Спасибо, но я до сих пор не понимаю, как указать использование репо. Я имею в виду, когда пользователь выбирает переключатель, мне нужно выбрать реализацию. Как? Вы имеете в виду, что у меня должны быть две фабрики (по одной для каждой реализации интерфейса rep)? Небольшой пример кода «radiobutton_changed()» был бы очень полезен :) – Thomas

+0

Смотрите мои правки и дайте мне знать, если это имеет смысл. –

+0

Еще раз спасибо! Теперь все ясно :) – Thomas

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