【发布时间】:2014-11-10 16:40:38
【问题描述】:
灵感来自Mark Seemann's post: Pattern Recognition: Abstract Factory or Service Locator?
我希望像这样写一个抽象工厂:
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();
}
然后,当我使用 Ninject 绑定 ToFactory() 时,它将创建 EmailIndicatorA 的实例。
如何使用 Ninject 绑定IAbstractFactory<T>,因为每种类型:
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 使用的是非通用的@987654338 @方法。
感谢您指出这一点,@PrestonGuillot! =)
也许我在这里过于复杂了......所以这是我的模型:
电子邮件指示符
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();
}
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的实例,为什么不在构造函数中包含这些实例?看起来你没有做任何需要你的 sn-p 抽象工厂的事情。 -
你是对的。也许我的例子没有很好地选择,我想不出其他任何东西。另外,
Abstract Factory模式的实现呢? -
不管怎样,您链接的博客文章直接回答了您的问题仙女“抽象工厂是一个泛型类型具有非泛型 Create 方法;服务定位器是一个 具有泛型 Create 方法的非泛型类型。”,你属于后者。
-
再想一想,你是对的。一路走来,我一定很迷茫。我很难理解
Abstract Factory模式的要点及其好处。 -
@PrestonGuillot:请查看我的问题编辑。 =)
标签: c# ninject ninject-extensions abstract-factory