与Ninject和EF使用个IAuthorizationFilter给出的DbContext已被释放错误 [英] Using IAuthorizationFilter with Ninject and EF gives DbContext has been disposed error

查看:177
本文介绍了与Ninject和EF使用个IAuthorizationFilter给出的DbContext已被释放错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用我的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已被释放的操作无法完成

System.InvalidOperationException: The operation cannot be completed because the DbContext has been disposed.

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已被释放错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆