【发布时间】:2018-01-30 22:37:19
【问题描述】:
我已经像这样配置了我的 EF 上下文
b.RegisterAssemblyTypes(webAssembly, coreAssembly)
.Where(t => t.IsAssignableTo<DbContext>())
.InstancePerLifetimeScope();
我想从使用我的 EF 上下文访问数据库的自定义授权属性中使用它。这意味着没有构造函数注入。我通过使用CommonSeviceLocator
来实现这一点 var csl = new AutofacServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => csl);
...
var user = await ServiceLocator.Current
.GetInstance<SiteContext>().FindAsync(id);
我发现如果浏览器使用此属性同时向路由发出两个请求,则会失败并显示“不支持多个连接”错误。看起来这可能是due to what is mentioned in this answer。我的猜测是 ServiceLocator 从根范围而不是 Web 请求范围解析,并且两个请求是冲突的(单独的请求都可以正常工作)。
当我更改为 InstancePerRequest() 时,这似乎证实了这一点,我从属性的任何调用中得到了这一点。
Autofac.Core.DependencyResolutionException No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is
being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
所以看起来ServiceLocator 可能根本不是要走的路。
如何从属性内部解析请求范围的SiteContext(使用服务定位器模式)?
【问题讨论】:
-
Standard Web API Filters are Singletons。你可以在这里查看。
-
@ErkanDemirel 是的,但它不像
ServiceLocator缓存响应,它在每次调用时都会获得一个新响应!我的猜测是过滤器代码在 Autofac 创建其请求范围之前运行。 -
它会在每个请求中获得一个新的,但它会在该请求中与控制器共享这个。 (我已经测试过了)。
-
@ErkanDemirel 这正是我想要的,但这不是正在发生的事情。大多数组件都会这样做,但是该属性似乎使用单例。
标签: entity-framework dependency-injection inversion-of-control autofac