【发布时间】:2016-10-24 11:27:04
【问题描述】:
我有一个使用带有 OWIN 的 Web API 5.23 构建的 Web 服务。我使用 Unity 作为 IOC 容器。
此 Web 服务由每 2 秒触发一次 http 请求的 Windows 服务使用。
windows服务启动时,web服务抛出如下异常:
发生 System.NotSupportedException H结果=-2146233067 Message=在前一个异步操作完成之前在此上下文上启动了第二个操作。使用 'await' 确保在此上下文上调用另一个方法之前已完成任何异步操作。不保证任何实例成员都是线程安全的。
据我所知,两个线程正在尝试使用同一个 DbContext 实例,因此在每个请求上创建一个新的 DbContext 应该可以解决我的问题。
查看 Unity 提供的 LifeTimeManagers,似乎 TransientLifetimeManager 是自
以来的必经之路TransientLifetimeManager。对于这个生命周期管理器,Unity 为每次调用 Resolve 或 ResolveAll 方法创建并返回请求类型的新实例。此生命周期管理器默认用于使用 RegisterType 方法注册的所有类型,除非您指定不同的生命周期管理器。
由于某种原因,这不起作用,我仍然遇到同样的异常。
经过一番搜索,我找到了PerRequestLifetimeManager 。但我不能使用它,因为我不想依赖 MVC。当我检查它的实现方式时,我注意到它依赖于 IHttpModule。我不确定是否可以使用它,因为我正在使用 OWIN 中间件来托管我的 Web 服务。
如何使用 OWIN 为 Web API 实现 PerRequestLifetimeManager?
详细信息以防我做错了:
public static class MiddlewareContainer
{
public static void Register(IUnityContainer container)
{
container.RegisterType<DbContext, LicenceDbContext>(new TransientLifetimeManager());
container.RegisterType<IdentityDbContext<IdentityUser>, LicenceDbContext>(new TransientLifetimeManager());
container.RegisterType<IOAuthAuthorizationServerProvider, LicenceAuthorizationProvider>(new TransientLifetimeManager(),
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<AuthorizationProviderLoggingInterceptionBehavior>());
container.RegisterType<IDeploymentAuthRepository, DeploymentAuthRepository>(new TransientLifetimeManager());
container.RegisterType(typeof (UserManager<>), typeof (UserManager<>) ,new TransientLifetimeManager());
container.RegisterType(typeof (IUserStore<>), typeof (UserStore<>), new TransientLifetimeManager());
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
container.RegisterType<IHttpActionResultProvider, HttpActionResultProvider>();
container.RegisterType<IClaimsIdentityFactory, ClaimsIdentityFactory>();
container.RegisterType<LoggingInterceptionBehavior, AuthorizationProviderLoggingInterceptionBehavior>();
container.RegisterType<ILogger, Logger>();
container.RegisterType<IIdentityProvider, IdentityProvider>();
container.RegisterType<IIdentityProviderFactory, IdentityProviderFactory>();
container.RegisterType<ILogger, Logger>();
container.RegisterType(typeof (IRepository<>), typeof (Repository<>));
container.RegisterType<IRepository<UserActivity>, UserActivityRepository>();
container.RegisterType<IRepository<Licence>, LicenceRepository>();
container.RegisterType<IJsonConverter, JsonConverter>();
container.RegisterType<IEqualityComparer<Message>, MessageComparer>();
container.RegisterType<System.Web.Http.ExceptionHandling.ExceptionLogger, GenericExceptionLogger>();
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
var container = new UnityContainer();
container.AddNewExtension<Interception>();
MiddlewareContainer.Register(container);
config.DependencyResolver = new UnityResolver(container);
ConfigureFilters(config, container);
ConfigureOAuth(app,container);
WebApiConfig.Register(config);
app.UseWebApi(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
}
【问题讨论】:
-
我也想看到一个答案。我尝试了很长一段时间来让 Unity 在每个请求中都能正常运行,但它从来没有奏效,并导致 EF 和 DbContext 出现问题。我已经切换到 SimpleInjector 以在需要时完成此任务,但我真的很想让 Unity 工作。
标签: c# asp.net-web-api owin