这是一个例子抽象工厂 http://sourcemaking.com/design_patterns/abstract_factory设计模式。这个想法是创建一个接缝以在类之间提供松散耦合,以便可以交换另一种类型的上下文,无论是出于测试目的还是为了扩展应用程序。
一般来说,工厂是一种管理短期依赖关系的方法,例如数据库连接。通常,框架公开一种注入工厂实例的方法,然后框架可以基于接口(在本例中为 IDatabaseFactory)作为框架和框架用户之间的契约来使用它。该框架将具有如下所示的代码:
public interface ISomeService
{
void DoSomething();
}
public class SomeService()
{
private readonly IDatabaseFactory factory;
// The factory is injected through the constructor
public SomeService(IDatabaseFactory factory)
{
this.factory = factory;
}
public void DoSomething()
{
using (EFMVCDataContex context = this.factory.Get())
{
// Run a LINQ query here using the context
} // This bracket disposes the context
}
}
然后,该服务可以被实例化,其生命周期比工厂创建的上下文要长得多。更重要的是,在这种情况下上下文总是得到正确处理。
现在,这样做的主要好处是您可以将 DatabaseFactory 与替代实现(通常称为里氏替换原则 http://www.oodesign.com/liskov-s-substitution-principle.html):
public class MyDatabaseFactory : Disposable, IDatabaseFactory
{
private EFMVCDataContex dataContext;
public EFMVCDataContex Get()
{
return dataContext ?? (dataContext = new AlternateDataContext());
}
protected override void DisposeCore()
{
if (dataContext != null)
dataContext.Dispose();
}
}
假设 AlternateDataContext 继承(或实现)EFFMCDataContex,MyDatabaseFactory 可以与 DatabaseFactory 进行同等交换,而无需对 SomeService 进行任何更改。
例如,MyDatabaseFactory 可以在构造函数中使用连接字符串进行编码,为您提供了一种连接到备用数据库的方法。
当然,这样做的另一个巨大好处是创建 IDatabaseFactory 的模拟实现,可用于测试 DoSomething 方法。在单元测试中,SomeService(被测类)应该是唯一使用的真实类,IDatabaseFactory 应该是一个模拟(可以通过手动编码类或使用模拟框架来完成)。