На основе сообщения Марка Симанна: Распознавание образов: абстрактная фабрика или локатор сервисов? сильный>а>
Я хочу написать абстрактную фабрику так:
public interface IAbstractFactory {
T Create<T>();
}
Затем свяжите его с помощью Ninject следующим образом:
IKernel kernel = new StandardKernel();
kernel.Bind<IAbstractFactory>().ToFactory();
Затем можно использовать его следующим образом:
public class CustomerServiceIndicatorsModel {
public CustomerServiceIndicatorsModel(IAbstractFactory factory) {
this.emailIndicatorA = factory.Create<EmailIndicatorA>();
this.emailIndicatorB = factory.Create<EmailIndicatorB>();
this.emailIndicatorC = factory.Create<EmailIndicatorC>();
}
}
Опять же, я нигде не ссылаюсь на ядро Ninject, и это работает. Ядро упоминается только в файле Global.asax.cs
для привязок.
Можно ли считать его приемлемой реализацией шаблона абстрактной фабрики?
Мне трудно понять смысл этого шаблона. Я четко понимаю шаблон Factory
как делегированный класс, который создает экземпляры данного типа.
public interface IEmailIndicatorAFactory {
EmailIndicatorA Create();
}
Затем, когда я свяжу его ToFactory()
с помощью Ninject, он создаст экземпляры EmailIndicatorA
.
Как связать IAbstractFactory<T>
с помощью Ninject, так как каждый тип:
IAbstractFactory<EmailIndicatorA>
IAbstractFactory<EmailIndicatorB>
IAbstractFactory<EmailIndicatorC>
считается вполне конкретным типом. И я не могу найти способ связать его с помощью Ninject
.
И я не вижу смысла писать такой интерфейс, если взамен придется писать:
public interface EmailIndicatorAFactory : IAbstractFactory<EmailIndicatorA> { }
public interface EmailIndicatorBFactory : IAbstractFactory<EmailIndicatorB> { }
public interface EmailIndicatorCFactory : IAbstractFactory<EmailIndicatorC> { }
После комментария @PrestonGuillot я попал в последнюю реализацию ServiceLocator
вместо AbstractFactory
, поскольку я использую общий метод Create<T>()
, а Abstract Factory
использует не универсальный метод Create()
.
Спасибо, что указали на это, @PrestonGuillot! знак равно
Возможно, я слишком усложняю... Итак, вот моя модель:
Индикатор электронной почты
public abstract EmailIndicator {
int EmailCount { get; set; }
DateTime OldestDateTimeReceived { get; set; }
}
Индикатор электронной почтыA
public class EmailIndicatorA : EmailIndicator { }
Индикатор электронной почтыB
public class EmailIndicatorB : EmailIndicator { }
Индикатор электронной почтыC
public class EmailIndicatorC : EmailIndicator { }
Репозиторий IEmailIndicatorRepository
public interface IEmailIndicatorRepository<T> where T : EmailIndicator {
T GetIndicator();
}
public class EmailIndicatorARepository : IEmailIndicatorRepository<EmailIndicatorA> {
public EmailIndicatorARepository(IExchangeService service
, IExchangeConfiguration configuration
, INetworkCredentialFactory credentialFactory) {
exchangeService = service;
exchangeService.Url = configuration.ExchangeUri;
exchangeService = credentialFactory.Create(configuration.Login, configuration.Password);
}
EmailIndicatorA GetIndicator() {
// Code to query Exchange through its Web services here...
}
}
И два других репозитория, подобных этому, существуют, так как мне приходится запрашивать три разных сервера Exchange в моем приложении.
Я считаю, что есть место для использования Abstract Factory
, и, поскольку я все еще изучаю шаблон, я просто еще не понимаю, как реализовать его в моей ситуации.
Если бы не сами индикаторы, возможно, я наконец смог бы разобраться в Abstract Factory
с моими репозиториями.
Насколько я понимаю, вот что я бы попробовал в качестве первого шага к решению:
IRepositoryFactory
public interface IRepositoryFactory<T> where T : class, new() {
T Create();
}
IEmailIndicatorARepositoryFactory
public interface IEmailIndicatorARepositoryFactory
: IRepositoryFactory<EmailIndicatorARepository> {
EmailIndicatorARepository CreateEmailIndicatorARepository();
}
IEmailIndicatorBRepositoryFactory
public interface IEmailIndicatorBRepositoryFactory
: IRepositoryFactory<EmailIndicatorBRepository> {
EmailIndicatorBRepository CreateEmailIndicatorBRepository();
}
А Абстрактная фабрика?
public abstract IEmailIndicatorRepositoryFactory
: IEmailIndicatorARepositoryFactory
, IEmailIndicatorBRepositoryFactory
, IEmailIndicatorCRepositoryFactory {
EmailIndicatorARepository CreateEmailIndicatorARepository() { // create instance here... }
EmailIndicatorBRepository CreateEmailIndicatorBRepository() { // create instance here... }
EmailIndicatorCRepository CreateEmailIndicatorCRepository() { // create instance here... }
}
Это лучший подход?
Я немного потерян и сбит с толку здесь.
EmailIndicatorA
,EmailIndicatorB
иEmailIndicatorC
для создания экземпляраCustomerServiceIndicatorsModel
, почему бы вам просто не добавить их в конструктор? Похоже, вы не делаете ничего, что требует абстрактной фабрики из вашего фрагмента. - person Preston Guillot   schedule 10.11.2014Abstract Factory
? - person Will Marcouiller   schedule 10.11.2014Abstract Factory
и его преимуществах. - person Will Marcouiller   schedule 10.11.2014