我有Global.asax
,如下面的代码:
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
// ....
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(typeof(IOCControllerFactory));
}
}
public class IOCControllerFactory : DefaultControllerFactory
{
private readonly IKernel kernel;
public IOCControllerFactory()
{
kernel = new StandardKernel(new NanocrmContainer());
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
return base.GetControllerInstance(requestContext, controllerType);
var controller = kernel.TryGet(controllerType) as IController;
if (controller == null)
return base.GetControllerInstance(requestContext, controllerType);
var standartController = controller as Controller;
if (standartController is IIoCController)
((IIoCController)standartController).SetIoc(kernel);
return standartController;
}
class NanocrmContainer : Ninject.Modules.NinjectModule
{
public override void Load()
{
// ...
Bind<DomainModel.Entities.db>().ToSelf().InRequestScope().WithConstructorArgument("connection", "Data Source=lims;Initial Catalog=nanocrm;Persist Security Info=True;User ID=***;Password=***");
}
}
}
在这种情况下,如果某个地方是类,则定义如下:
public class UserRepository : IUserRepository
{
private db dataContext;
private IUserGroupRepository userGroupRepository;
public UserRepository(db dataContext, IUserGroupRepository userGroupRepository)
{
this.dataContext = dataContext;
this.userGroupRepository = userGroupRepository;
}
}
然后由Ninject创建dataContext
实例(如果在此请求范围内没有创建任何人)。
现在麻烦的是 - 在哪里调用dataContext
方法.Dispose()
?
UPD :
所以我按照 KeeperOfTheSoul 的建议,以这种方式解决了问题:
public override void ReleaseController(IController controller)
{
base.ReleaseController(controller);
var db = kernel.Get<DomainModel.Entities.db>();
db.Dispose();
}
答案 0 :(得分:3)
处理此问题的好地方是IControllerFactory.ReleaseController,例如
public override void ReleaseController() {
base.ReleaseController();
//Do whatever you need to clean up the IoC container here
}
在NInject中,这可以通过使用activation block进行范围处理,在创建控制器时,在创建控制器时可以将激活块存储在HttpContext的当前项中,在ReleaseController期间,您可以检索先前创建的激活阻止并处置它。
您还可以考虑使用InScope
并让自定义范围实现INotifyWhenDisposed
。之后,使用情况与激活块相同,但现在将范围存储在HttpContext的当前项中。
答案 1 :(得分:2)
有时用于处理数据库连接的模式是从终结者调用Dispose
。
public class db : IDisposable {
//called by the garbage collector
~db() {
//Call dispose to make sure the resources are cleaned up
Dispose(false);
}
//IDisposable implementation
public void Dispose() {
Dispose(true);
}
//subclasses of db can override Dispose(bool) and clean up their own fields
protected virtual void Dispose (bool disposing) {
if (disposing) {
//Supress finalization as all resources are released by this method
//Calling Dispose on IDisposable members should be done here
GC.SupressFinalize();
}
//Clean up unmanaged resources
//Do not call other objects as they might be already collected if called from the finalizer
}
}
答案 2 :(得分:1)
您可以将其挂钩到Application_EndRequest。