【问题标题】:Instantiate service layer and repositories once during life of web application在 Web 应用程序的生命周期内实例化服务层和存储库一次
【发布时间】:2012-12-17 22:33:46
【问题描述】:
在我的 Web 应用程序的生命周期中,我知道我的所有服务和存储库都会被调用。我想在 Web 应用程序启动期间实例化它们一次,并在我的代码中引用实例化的引用。
是否有一种通用模式可以在 Web 应用程序的生命周期内只实例化一次服务/存储库,而不使它们成为静态或单例。
我想避免将我的服务/存储库设为静态类或单例以实现可测试性,但是当它们被设计为无状态时,在每个 Web 请求上实例化它们似乎并不正确,而且我知道它们在生命周期中都将被需要应用程序。
我正在使用 c#/asp.net。
【问题讨论】:
标签:
c#
.net
design-patterns
ddd-repositories
【解决方案1】:
你需要的概念叫做 IoC/DI,有很多框架可以做到这一点。当你有一个像 CustomerService 这样的类并且你需要一个 CustomerRepository 时,根据定义,这是一个依赖项,你应该通过 CustomerService 的构造函数传递它——但是问题是你将在哪里实例化 CustomerService?好吧,使用该服务的人也应该通过构造函数获得它,它可能是 CustomerPresenter 或其他一些无关紧要的类。我的观点是,通过依赖注入,您可以将代码构建到一个非常单一的点,在该点上,IoC / DI 框架会根据您的规则解决这些依赖关系。
在程序的最顶部,您会看到如下内容:
ICustomerPresenter presenter = IoC.Resolve<ICustomerPresenter>();
一切都会在幕后自动融合在一起。
为了实现这一点,下面是一个使用 StructureMap 的示例:
For<ICustomerPresenter>().Use<CustomerPresenter>();
For<ICustomerService>().Singleton().Use<CustomerService();
For<ICustomerRepository>().Singleton().Use<CustomerRepository>();
这样,您就可以保持可测试性。我在这里简化了很多,所以按原样使用并不多,但是网上有很多 IoC / DI 资源,所以请查看。
注意:对于 Web 应用程序,您需要检查每个请求的处理生命周期,您很少有整个 Web 应用程序的单例。
【解决方案2】:
依赖注入框架会处理你的对象的生命周期。
例如
container.RegisterType<MyService>().Singleton();
有许多 DI 框架选择最适合您的。