Вдохновленный из Mark Seemann's post: Pattern Recognition: Abstract Factory or Service Locator?Является ли это правильной или жизнеспособной реализацией шаблона Abstract Factory?
Я хотел бы написать абстрактную фабрику, как так:
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>();
}
}
Опять же, я не refe где-нибудь, где это происходит, и что это работает. Ядро упоминается только в файле 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! =)
Возможно, я преувеличиваю здесь ...Так вот моя модель:
EmailIndicator
public abstract EmailIndicator {
int EmailCount { get; set; }
DateTime OldestDateTimeReceived { get; set; }
}
EmailIndicatorA
public class EmailIndicatorA : EmailIndicator { }
EmailIndicatorB
public class EmailIndicatorB : EmailIndicator { }
EmailIndicatorC
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();
}
IEmailIndicatorBRepositor yFactory
public interface IEmailIndicatorBRepositoryFactory
: IRepositoryFactory<EmailIndicatorBRepository> {
EmailIndicatorBRepository CreateEmailIndicatorBRepository();
}
И Abstract Factory?
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', почему бы вам просто не использовать их в конструкторе? Похоже, вы не делаете ничего, что требует от фабрики абстрактной фабрики. –
Вы правы. Возможно, мой пример не очень хорошо подобрался, и я не мог думать ни о чем другом с моей головы. Кроме того, как насчет реализации шаблона «Абстрактная фабрика»? –
Независимо от того, сообщение в блоге, на которое вы ссылаетесь, напрямую отвечает на ваш вопрос. «Абстрактная фабрика - это общий тип * с универсальным методом Create *, локатор сервисов - это не общий тип с универсальным методом Create. *", вы попадаете в последнее. –