是StructureMap HttpContextScoped必备吗?

时间:2012-12-10 09:41:41

标签: asp.net-mvc-3 entity-framework structuremap session-per-request

我在EF code firstMVCStructureMap的教程中看到了如下代码,以创建Context Per Request模式:

    protected void Application_Start()
    {
        ...

        initStructureMap();

    }

    private static void initStructureMap()
    {

        ObjectFactory.Initialize(x =>
        {
            x.For<IUnitOfWork>().HttpContextScoped().Use(() => new Context());
            x.For<IFirstEntity>().Use<FirstEntity>();
            x.For<ISecondEntity>().Use<SecondEntity>();
            x.For<IThirdEntity>().Use<ThirdEntity>();
        });

        ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
    }

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
    }


public class StructureMapControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return ObjectFactory.GetInstance(controllerType) as Controller;
    }
}

FirstEntitySecondEntity和...在构造函数中都需要IunitOfWork

正如您所看到的那样,HttpContextScoped()仅使用Context而不是其他EndRequest,而ReleaseAndDisposeAllHttpScopedObjects()事件则使用Service layer Interfaces

1-这是一种正确的方法吗?

2-我应该将HttpContextScoped()用于所有其他IUnitOfWork还是仅用于x.For<IFirstEntity>().Use<FirstEntity>(); ? e.g

x.For<IFirstEntity>().HttpContextScoped().Use(() => new FirstEntity());

ReleaseAndDisposeAllHttpScopedObjects()

3- Context处置所有实例或只处理{{1}}?

1 个答案:

答案 0 :(得分:8)

Web应用程序的约定是在整个http请求期间保持相同的ORM上下文/ UnitOfWork。这是为了在请求期间使用相同的实体,保持数据一致并最小化数据库调用。 HttpContextScoped生命周期确保在请求所有依赖于它的实例期间使用相同的UoW实例。

所以1)是的,这是正确的

关于“服务层接口”的其余部分,它取决于在整个请求期间它是否需要是同一个实例。问问自己:“在整个请求期间是否需要此对象的状态”?对于大多数“服务”而言,情况并非如此。还要注意,制作“HttpContextScoped”的东西也会使所有它的依赖关系保持在该范围内。

这让我说2)在大多数情况下,没有

ReleaseAndDisposeAllHttpScopedObjects处理使用HttpContextScoped注册的容器中的所有对象。默认情况下,对象的范围是在Structuremap中的瞬态(每个调用的新实例)。

所以3)只会处理IUnitOfWork实例。