创建一个单一的并不罕见ObjectContext
每个网络请求。我在我的网络应用程序中执行此操作。然而,IMO,该页面不应该知道ObjectContext
.
由于您已经在讨论在服务的构造函数中注入上下文,因此请查看依赖项注入(如果您尚未使用它)。当您使用依赖项注入容器时,您可以让容器为您创建该服务并将对象上下文注入该容器中。您的页面唯一要做的就是从容器请求该服务(理想情况下,您甚至可以将该服务注入到该页面的构造函数中,但这对于 Web 表单来说是不可能的)。
您的页面将如下所示:
public class MyPage : Page
{
private readonly IMyService service;
public MyPage()
{
this.service = Global.GetInstance<IMyService>();
}
protected void Btn1_OnClick(object s, EventArgs e)
{
this.service.DoYourThing(this.TextBox1.Text);
}
}
在应用程序的启动路径(Global.asax)中,您可以像这样配置依赖注入框架:
private static Container Container;
public static T GetInstance<T>() where T : class
{
return container.GetInstance<T>();
}
void Application_Start(object sender, EventArgs e)
{
var container = new Container();
string connectionString = ConfigurationManager
.ConnectionStrings["MyCon"].ConnectionString;
// Allow the container to resolve your context and
// tell it to create a single instance per request.
container.RegisterPerWebRequest<MyContext>(() =>
new MyContext(connectionString));
// Tell the container to return a new instance of
// MyRealService every time a IMyService is requested.
// When MyContext is a constructor argument, it will
// be injected into MyRealService.
container.Register<IMyService, MyRealService>();
Container = container;
}
在这些例子中我使用了简易注射器依赖注入容器,尽管任何 DI 容器都可以。这RegisterPerWebRequest
不是核心库的一部分,但是可作为 (NuGet) 扩展包使用。该套餐确保您的ObjectContext
当网络请求结束时被处理。
乍一看这可能看起来很复杂,但这样网页就不必担心创建和处置的任何细节ObjectContext
.
此外,将执行用例的逻辑放置在单个类中:命令。让命令(或系统)确保该操作的原子性。不要让页面对此负责,也不要在请求结束时提交,因为那时您将不知道是否可以调用提交。不,让命令自己处理这个问题。这是一篇关于编写业务命令的文章.
此建议也适用于 ASP.NET MVC,尽管您不应该调用Global.GetInstance<IMyService>()
在 Controller 的构造函数内部,但只需使用构造函数注入(因为 MVC 对此有很好的支持)并使用MVC3集成包.
还看一下这个 Stackoverflow 问题,它讨论了之间的选择IObjectContextFactory
或有一个ObjectContext
根据要求。