我正在尝试在IAuthorizationFilter
的实现中使用我的UnitOfWork,但在我在几个页面之间导航后,我得到了这个例外:
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...
}
}
我能够解决这个问题:
// NinjectMappings
Bind<IUnitOfWork>()
.ToMethod(m => GetUnitOfWork())
.WhenInjectedExactlyInto(typeof(PermissionFilter));
private IUnitOfWork GetUnitOfWork()
{
return new UnitOfWork(new MyContext());
}
现在的问题是{app}启动时只调用GetUnitOfWork
一次。我尝试在InTransientScope
和InRequestScope
之间交替无效。因此,不会检索数据库的更新,而是我的UnitOfWork始终返回相同的数据。
我已经阅读了很多关于DbContext has been disposed
的问题,但没有一个问题正在实施IAuthorizationFilter
。
解决此问题的最佳方法是什么?我想避免使用过滤器内的new
或using()
或使用服务定位器模式。
答案 0 :(得分:1)
您的问题来自于您的MyContext在请求范围内实例化并在请求结束时处理。
要解决此问题,避免使用new()
,using
或ServiceLocator模式,您可以依赖专用的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.Extensions.Factory这样的Ninject Factory扩展来在Func<PermissionFilter>
构造函数中实现PermissionFilterProvider
工厂模式。
另外,我不确定IUnitOfWork
的范围。不应该与您的MyContext
相同吗?