在我开始在过滤器中使用DI后,我得到了下一个EF异常:
在上一次异步操作完成之前,在此上下文中启动了第二个操作。使用'等待'确保在调用此上下文中的另一个方法之前已完成任何异步操作。不保证任何实例成员都是线程安全的。
我使用Unity作为我的IoC容器。我的设置如下:
config.DependencyResolver = new UnityHierarchicalDependencyResolver(container);
var providers = GlobalConfiguration.Configuration.Services.GetFilterProviders().ToList();
//adding IFilterProvider provided by Unity
GlobalConfiguration.Configuration.Services.Add(
typeof(IFilterProvider),
new UnityActionFilterProvider(UnityConfig.GetConfiguredContainer()));
var defaultprovider = providers.First(p => p is ActionDescriptorFilterProvider);
//removing default IFilterProvider
GlobalConfiguration.Configuration.Services.Remove(
typeof(IFilterProvider),
defaultprovider);
然后我按照以下方式注册我的过滤器进行授权:
var authFilter = config.DependencyResolver.GetService(typeof(MyFilterType));
config.Filters.Add((MyFilterType)authFilter);
我的授权过滤器如下所示:
public class MyFilterType : IAuthorizationFilter
{
private readonly MyServiceInterfaceType _service;
public MyFilterType(MyServiceInterfaceType service)
{
_service = service;
}
public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext,
CancellationToken cancellationToken,
Func<Task<HttpResponseMessage>> continuation)
{
var res = await _service.SomeAction();
//the rest doesn't matter
}
}
MyServiceInterfaceType
内部聚合MyRepositoryInterfaceType
。所以它只是通常的Service-Repository
模式。
内部MyRepositoryInterfaceType
EF上下文已初始化。
所以,关于例外。我知道这意味着什么 - 有对上下文的并发异步调用。我认为这是因为这两行:
var authFilter = config.DependencyResolver.GetService(typeof(MyFilterType));
config.Filters.Add((MyFilterType)authFilter);
过滤器实例基本上存储在单例中。因此,每个过滤器调用都由相同的EF上下文实例提供,这就是存在异常的原因。
(如果我错了,请纠正我。)
我的问题是:
是否可以为每次调用创建我的MyFilterType
过滤器的新实例以避免这些异常?
答案 0 :(得分:1)
您需要在方法内部进行服务定位。
var requestScope = actionContext.Request.GetDependencyScope();
var myService = requestScope.GetService(MyServiceInterfaceType) as MyServiceInterfaceType;
Autofac有自己的过滤器,如果你使用它而不是Unity,你可以使用它,但我不认为Unity提供类似的东西。 Autofac文档提供了很好的解释: http://docs.autofac.org/en/latest/integration/webapi.html#provide-filters-via-dependency-injection