IAuthenticationFilter 中的 C# Ninject Web API 异步查询导致实体框架中的多个操作错误
Posted
技术标签:
【中文标题】IAuthenticationFilter 中的 C# Ninject Web API 异步查询导致实体框架中的多个操作错误【英文标题】:C# Ninject Web API async query in IAuthenticationFilter causes multiple operations error in entity framework 【发布时间】:2017-10-27 14:39:41 【问题描述】:我正在使用带有 Ninject 的 Web API 2,当我有多个并行 HTTP 调用时出现以下错误。
在前一个异步操作完成之前,在此上下文上启动了第二个操作。使用 'await' 确保在此上下文上调用另一个方法之前已完成任何异步操作。不保证任何实例成员都是线程安全的。
我之前没有收到此错误,从数据库中检索数据的所有代码都是异步的,所以我认为这是 Ninject 范围问题。
NinjectWebCommon
kernel.BindHttpFilter<MyAuthenticateFilter>(FilterScope.Action);
// Database context
kernel.Bind<IUnitOfWorkAsyncFactory>().To<UnitOfWorkAsyncFactory>().InRequestScope();
kernel.Bind<IUnitOfWorkAsync>().To<UnitOfWork>().InRequestScope();
kernel.Bind<IDataFactory>().To<DataFactory>().InRequestScope();
所有应用程序和域处理程序也是异步的,并使用相同的 DataFactory
和 UnitOfWorkAsyncFactory
。IAuthenticationFilter
似乎存在线程问题。
用于DbContext
的工厂模式。
public class DataFactory : Disposable, IDataFactory
private MyContext DbContext get; set;
public IDataContextAsync GetDataContext()
return DbContext ?? (DbContext = new MyContext());
public void AfterDispose()
DbContext = null;
public DataFactory()
public DataFactory(MyContext context)
DbContext = context;
【问题讨论】:
你是不是不小心把async
的东西一发不可收拾?
我看不到,尝试在IAuthenticationFilter
中的async Task AuthenticateAsync
方法上从数据库中读取会话实体时发生错误。当一个 http 调用触发读取并返回一个文件时会发生这种情况,该文件也标记为async
。
【参考方案1】:
我记得前段时间在 WebApi 中的过滤器注入问题和范围丢失。
据我所知,使用IDependencyResolver
的这个实现(不记得我在哪里得到它)解决了这个问题。
using System.Web.Http.Dependencies;
using global::Ninject.Syntax;
public class DependencyResolverWebApiNinject : DependencyScopeWebApiNinject, IDependencyResolver
public DependencyResolverWebApiNinject(IResolutionRoot resolutionRoot)
: base(resolutionRoot)
public virtual IDependencyScope BeginScope()
return this;
DependencyScopeWebApiNinject
在哪里:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using global::Ninject;
using global::Ninject.Infrastructure.Disposal;
using global::Ninject.Parameters;
using global::Ninject.Syntax;
public class DependencyScopeWebApiNinject : DisposableObject, IDependencyScope
/// <summary>
/// Initializes a new instance of the <see cref="DependencyScopeWebApiNinject"/> class.
/// </summary>
/// <param name="resolutionRoot">The resolution root.</param>
public DependencyScopeWebApiNinject(IResolutionRoot resolutionRoot)
this.ResolutionRoot = resolutionRoot;
/// <summary>
/// Gets the resolution root.
/// </summary>
/// <value>The resolution root.</value>
protected IResolutionRoot ResolutionRoot
get;
private set;
/// <summary>
/// Gets the service of the specified type.
/// </summary>
/// <param name="serviceType">The type of the service.</param>
/// <returns>The service instance or <see langword="null"/> if none is configured.</returns>
public object GetService(Type serviceType)
var request = this.ResolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return this.ResolutionRoot.Resolve(request).SingleOrDefault();
/// <summary>
/// Gets the services of the specifies type.
/// </summary>
/// <param name="serviceType">The type of the service.</param>
/// <returns>All service instances or an empty enumerable if none is configured.</returns>
public IEnumerable<object> GetServices(Type serviceType)
return this.ResolutionRoot.GetAll(serviceType).ToList();
希望这会有所帮助
【讨论】:
我尝试使用它,但它导致了以下错误。 '使用从 ModelValidatorProvider 到 NinjectDefaultModelValidatorProvider 的绑定激活 ModelValidatorProvider 时出错在两个服务的构造函数之间检测到循环依赖。 似乎 Web API 2 不推荐使用此方法。GlobalConfiguration.Configuration.DependencyResolver = new DependencyResolverWebApiNinject(kernel);
@Raybbo 除非您使用 Ninject 的 ModelValidatorProvider,否则您还应该将此行 kernel.Unbind<ModelValidatorProvider>();
添加到您的 NinjectWebCommon 文件中以上是关于IAuthenticationFilter 中的 C# Ninject Web API 异步查询导致实体框架中的多个操作错误的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET MVC 控制器通过继承控制器来达到 过滤 并且多了一个IAuthenticationFilter
从 Web Api 2 IAuthenticationFilter AuthenticateAsync 方法设置 cookie