我在EF code first
,MVC
和StructureMap
的教程中看到了如下代码,以创建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;
}
}
FirstEntity
,SecondEntity
和...在构造函数中都需要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}}?
答案 0 :(得分:8)
Web应用程序的约定是在整个http请求期间保持相同的ORM上下文/ UnitOfWork。这是为了在请求期间使用相同的实体,保持数据一致并最小化数据库调用。 HttpContextScoped
生命周期确保在请求所有依赖于它的实例期间使用相同的UoW实例。
所以1)是的,这是正确的
关于“服务层接口”的其余部分,它取决于在整个请求期间它是否需要是同一个实例。问问自己:“在整个请求期间是否需要此对象的状态”?对于大多数“服务”而言,情况并非如此。还要注意,制作“HttpContextScoped”的东西也会使所有它的依赖关系保持在该范围内。
这让我说2)在大多数情况下,没有
ReleaseAndDisposeAllHttpScopedObjects
处理使用HttpContextScoped
注册的容器中的所有对象。默认情况下,对象的范围是在Structuremap中的瞬态(每个调用的新实例)。
所以3)只会处理IUnitOfWork
实例。