簡體   English   中英

使用IAuthorizationFilter和Ninject和EF給DbContext配置了錯誤

[英]Using IAuthorizationFilter with Ninject and EF gives DbContext has been disposed error

我正在嘗試在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());
}

現在的問題是GetUnitOfWork只在應用啟動時調用一次。 我嘗試在InTransientScopeInRequestScope之間交替無濟於事。 因此,不會檢索數據庫的更新,而是我的UnitOfWork始終返回相同的數據。

我已經閱讀了很多處理DbContext has been disposed問題,但是他們都沒有實現IAuthorizationFilter

解決這個問題的最佳方法是什么? 我想避免using()過濾器中的newusing()或使用Service Locator模式。

您的問題來自於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 Factory擴展,如Ninject.Extensions.Factory,以在PermissionFilterProvider構造函數中實現Func<PermissionFilter>工廠模式。

另外,我不確定您的IUnitOfWork的范圍。 它不應該與你的MyContext相同嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM