问题描述
我想用我的UnitOfWork 个IAuthorizationFilter
的实现里面,但在我的几个页面之间导航我得到这个异常:
I'm trying to use my UnitOfWork inside an implementation of IAuthorizationFilter
, but after I navigate between a few pages I get this exception:
System.InvalidOperationException:因的DbContext已被释放的操作无法完成
FilterConfig.cs
filters.Add(DependencyResolver.Current.GetService(typeof(PermissionFilter)));
NinjectMappings.cs
public class NinjectMappings : NinjectModule
{
public override void Load()
{
Bind<MyContext>().ToSelf().InRequestScope();
Bind<IUnitOfWork>().To<UnitOfWork>();
}
}
PermissionFilter.cs
public class PermissionFilter : IAuthorizationFilter
{
public PermissionFilter(IUnitOfWork unitOfWork)
{
// etc...
}
}
我是能够解决这个问题有:
I was able to get around this with:
// NinjectMappings
Bind<IUnitOfWork>()
.ToMethod(m => GetUnitOfWork())
.WhenInjectedExactlyInto(typeof(PermissionFilter));
private IUnitOfWork GetUnitOfWork()
{
return new UnitOfWork(new MyContext());
}
现在的问题是, GetUnitOfWork
只调用一次,在应用程序启动。我试图 InTransientScope
和 InRequestScope
之间交替无济于事。因此,更新到数据库中检索不到,而不是我的UnitOfWork总是返回相同的数据。
The problem now is that GetUnitOfWork
is only called once, at app start. I tried alternating between InTransientScope
and InRequestScope
to no avail. So updates to the database are not retrieved, instead my UnitOfWork always returns the same data.
我已阅读处理的DbContext已处置了不少问题
但他们没有正在实施的个IAuthorizationFilter
I have read quite a few questions dealing with DbContext has been disposed
but none of them were implementing an IAuthorizationFilter
.
什么是解决这个问题的最好方法?我想,以避免新
或使用()
在过滤器内或使用Service Locator模式。
What is the best way to solve this? I'd like to avoid new
or using()
inside the filter or using the Service Locator pattern.
推荐答案
您的问题来自于一个事实,你MyContext是在要求的范围实例化,并设置在请求结束。
Your problem comes from the fact that your MyContext is instantiated in the scope of a request and is disposed at the end of the request.
要解决这个问题,避免新()
,使用
或服务定位模式,你可以依靠专用 IFilterProvider
To solve this avoiding new()
, using
, or ServiceLocator pattern, you may rely on a dedicated IFilterProvider
public class PermissionFilterProvider : IFilterProvider
{
private readonly Func<PermissionFilter> _permissionFilterFactory = null;
public PermissionFilterProvider(Func<PermissionFilter> filterFactory)
{
_permissionFilterFactory = filterFactory;
}
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = new List<Filter>();
// instantiate PermissionFilter action filter
filters.Add(new Filter(_permissionFilterFactory(), FilterScope.Action, 0));
return filters;
}
}
您绑定随后将是:
public class NinjectMappings : NinjectModule
{
public override void Load()
{
Bind<MyContext>().ToSelf().InRequestScope();
Bind<IUnitOfWork>().To<UnitOfWork>();
Bind<IFilterProvider>().To<PermissionFilterProvider>();
Bind<PermissionFilter>().ToSelf();
}
}
请注意,您将需要一个Ninject厂扩展如 Ninject.Extensions.Factory 一>实现 Func键&LT; PermissionFilter&gt;在
工厂模式。 PermissionFilterProvider
构造
Note that you will need an Ninject Factory extension like Ninject.Extensions.Factory to achieve the Func<PermissionFilter>
factory pattern in PermissionFilterProvider
constructor.
另外,我不知道的范围,你的 IUnitOfWork
。难道不应该是一样的 MyContext
?
Also, I am not sure of the scope of your IUnitOfWork
. Shouldn't it be the same as your MyContext
?
这篇关于与Ninject和EF使用个IAuthorizationFilter给出的DbContext已被释放错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!