我有一个在我的开发环境中正常工作的N层解决方案。显然它也适用于生产环境,但有时执行失败。我不懂为什么。我只知道数据库没有任何变化,没有看到有用的错误,也没有写入日志。 我的假设是一个并发问题。我认为,一旦初始化实体框架上下文,当我尝试做多个选择时,某些事情就会失败。
这里我的解决方案是如何构建的
在外观中我注入了实体框架上下文。这里是我的web.config服务接口的配置:
<containers>
<container>
<types>
<register type="it.MC.IContext.IDataContext, IContext"
mapTo="it.MC.EntityFrameworkContext.PublicAreaContext, EntityFrameworkContext">
<lifetime type="singleton" />
</register>
<register type="it.MC.IFacade.IPublicAreaFacade, IFacade"
mapTo="it.MC.Facade.PublicAreaFacade, Facade">
<interceptor type="TransparentProxyInterceptor" />
<lifetime type="singleton" />
<constructor>
<param name="context" type="it.MC.IContext.IDataContext, IContext"/>
</constructor>
</register>
</types>
</container>
</containers>
如您所见,我的背景和外观是单身。我认为两者都是错的。我认为Facade实体Framewrk上下文应该是每个请求都是instanciate。我认为这也将解决并发问题。
有人可以帮我纠正我的代码吗?
谢谢
答案 0 :(得分:1)
我知道你的问题是:
有人可以帮我纠正我的代码吗?
我这样读了:
任何人都可以帮我更改此代码,以便每次请求重新初始化
IContext
和IFacade
。
有了这样说......是的,我也怀疑你想让你的IContext
成为一个单身人士。
Why you shouldn't use singleton DataContexts in Entity Framework
如果这就是您想要的,那么您可以将生命周期管理者更改为PerRequestLifetimeManager
。请注意,您可能需要Unity.Mvc NuGet包。
<containers>
<container>
<types>
<register type="it.MC.IContext.IDataContext, IContext"
mapTo="it.MC.EntityFrameworkContext.PublicAreaContext, EntityFrameworkContext">
<lifetime type="Microsoft.Practices.Unity.PerRequestLifetimeManager, Microsoft.Practices.Unity.Mvc" />
</register>
<register type="it.MC.IFacade.IPublicAreaFacade, IFacade"
mapTo="it.MC.Facade.PublicAreaFacade, Facade">
<interceptor type="TransparentProxyInterceptor" />
<lifetime type="Microsoft.Practices.Unity.PerRequestLifetimeManager, Microsoft.Practices.Unity.Mvc" />
<constructor>
<param name="context" type="it.MC.IContext.IDataContext, IContext"/>
</constructor>
</register>
</types>
</container>
</containers>
在投入制作之前,我建议您阅读this post关于PerRequestLifetimeManager
。
其目的是仅为每个请求实例化一个实例, 这可能(例如)防止冗余操作和查找 在一次请求过程中。
危险在于,如果有人认为创建的对象是好的 在请求期间存储状态的地方。依赖的想法 注入是一个类接收依赖(通常是一个 界面)并且不知道&#34;关于它的任何事情,除了它 实现该接口。
另外,请考虑一下Facade
,以及如果重新启动每个请求,它将如何运作。它是否在初始化时执行任何繁重的操作?您可能想要考虑那个人的终身经理。
<强>更新强>
由于您使用的是WebAPI,因此您应该能够使用HierarchicalLifetimeManager
。
http://www.asp.net/web-api/overview/advanced/dependency-injection
附加到HttpConfiguration对象的依赖项解析器具有 全球范围。当Web API创建控制器时,它会调用BeginScope。 此方法返回表示子范围的IDependencyScope。
Web API然后在子范围上调用GetService来创建 控制器。请求完成后,Web API将调用Dispose 儿童范围。使用Dispose方法处理控制器 的依赖关系。
http://www.devtrends.co.uk/blog/introducing-the-unity.webapi-nuget-package
如果您要注册任何实现IDisposable的组件,请执行此操作 作为实体框架的DbContext,您需要确保这些 组件在请求结束时被处理掉。这是实现的 通过使用HierarchicalLifetimeManager注册这些组件。