使用后处理ObjectContext(按请求)

时间:2011-06-09 12:46:58

标签: c# asp.net-mvc entity-framework inversion-of-control

我正在使用创建一个ObjectContext per-request概念。从技术上讲,我将ObjectContext实例添加到HttpContext.Current.Items。但我不知道如何正确杀死这个实例。使用HttpModule并在其中部署ObjectContext是否安全?我的意思是,可能会为任何类型的请求调用HttpModule。我不想使用DI / IoC问题,因为项目需要轻量级(不允许第三方库)。

更新:这里简单的代码: 创建了每个请求的ObjectContext(实体类)

public static class ObjectContextPerRequest
{
    public const string ObjectKey = "_per_request_context_key";

    public static Entities PerRequest
    {
        get
        {
            if (HttpContext.Current.Items[ObjectKey] != null)
            {
                var eContext = new Entities();
                HttpContext.Current.Items.Add(ObjectKey, eContext);

                return eContext;
            }

            return HttpContext.Current.Items[ObjectKey] as Entities;
        }
    }
}

和处理器模块:

class ObjectContextManagerModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.EndRequest += (s, e) => { Dispose(); };
    }

    public void Dispose()
    {
        if (HttpContext.Current.Items[ObjectContextPerRequest.ObjectKey] != null)
        {
            var edmx = (ObjectContext)HttpContext.Current.Items[ObjectContextPerRequest.ObjectKey];
            edmx.Dispose();
            edmx = null;
        }
    }
}

1 个答案:

答案 0 :(得分:5)

在BeginRequest期间创建上下文然后在EndRequest或ReleaseRequestState(可能是EndRequest)期间处理它会更安全。 Init是模块启动的时候,Dispose是模块本身被放置的时候,并且每次请求都不会创建和处理模块。

*评论更新*

模块应该使用其Init方法附加到应用程序事件,如下所示:

public void Init(HttpApplication app)
{
   app.BeginRequest += new EventHandler(OnBeginRequest);
   app.EndRequest += new EventHandler(OnEndRequest);
}

请注意,还有其他语法可用,但这是MSDN上记录的语法。

这将触发每个到达您的应用程序的请求。因此,如果您的IIS设置通过应用程序路由静态文件请求(例如图像和css文件)(在集成管道模式下对于IIS 7也是如此),那么您的事件处理程序需要通过在案例中不启动ObjectContext实例来解决这个问题你不需要一个。

* MVC *更新

由于您正在使用MVC应用程序,因此您还可以考虑使用OnActionExecuting和OnActionExecuted调用在控制器基类或actionfilter中执行此操作。

作为ActionFilter,您可以确保仅将其应用于需要数据上下文的控制器。