Entity framework 如何从自定义属性解析Autofac每请求服务
我已经像这样配置了我的EF上下文Entity framework 如何从自定义属性解析Autofac每请求服务,entity-framework,dependency-injection,inversion-of-control,autofac,Entity Framework,Dependency Injection,Inversion Of Control,Autofac,我已经像这样配置了我的EF上下文 b.RegisterAssemblyTypes(webAssembly, coreAssembly) .Where(t => t.IsAssignableTo<DbContext>()) .InstancePerLifetimeScope(); 因此,似乎ServiceLocator根本就不是一个好办法 如何从属性内部解析请求范围SiteContext(使用服务定位器模式)?您
b.RegisterAssemblyTypes(webAssembly, coreAssembly)
.Where(t => t.IsAssignableTo<DbContext>())
.InstancePerLifetimeScope();
因此,似乎ServiceLocator
根本就不是一个好办法
如何从属性内部解析请求范围
SiteContext
(使用服务定位器模式)?您的问题源于您试图将行为放入属性内部这一事实。属性用于定义代码元素和程序集上的元数据,而不是行为
微软对动作过滤器属性的营销导致人们将过滤器和属性放在同一个类中,从而使DI的实现走上了错误的道路。如本文所述,解决方案是将其分为两类:
IFilterProvider
解析过滤器,如中所示
一旦你意识到属性本身不应该做任何事情,那么将它们与DI一起使用就相当简单了。你的问题源于你试图将行为放入属性内部这一事实。属性用于定义代码元素和程序集上的元数据,而不是行为 微软对动作过滤器属性的营销导致人们将过滤器和属性放在同一个类中,从而使DI的实现走上了错误的道路。如本文所述,解决方案是将其分为两类:
IFilterProvider
解析过滤器,如中所示
一旦您意识到属性本身不应该做任何事情,那么将它们与DI结合使用就相当简单了。。您可以在这里检查。@ErkanDemirel是的,但它不像
ServiceLocator
缓存响应,它在每次调用时都会得到一个新的响应!我猜过滤代码在Autofac创建其请求作用域之前运行。它将在每个请求中获得新的作用域,但它将在该请求中与控制器共享。(我已经测试过了。)@ErkanDemirel这正是我想要的,但事实并非如此。大多数组件都会这样做,但是该属性似乎使用单例。。您可以在这里检查。@ErkanDemirel是的,但它不像ServiceLocator
缓存响应,它在每次调用时都会得到一个新的响应!我猜过滤代码在Autofac创建其请求作用域之前运行。它将在每个请求中获得新的作用域,但它将在该请求中与控制器共享。(我已经测试过了。)@ErkanDemirel这正是我想要的,但事实并非如此。大多数组件都会这样做,但是属性似乎使用了单例。好吧,我明白你的意思了……但在第一个示例中,至少不会有相同的问题吗?过滤器在全局范围内解析,而不是在AutofacWebRequest
范围内解析,因此将是一个单例。如果属性本身只有一个实例,那么所有的生命周期都与服务定位器模式相同,不是吗?正如Erkan在评论中指出的,有两种方法可以解决这个问题1)使用Autofac接口而不是WebAPI接口2)使用依赖范围中的服务定位器(这是通过上下文传递的)。请参阅。可能还有第三个选项更为DI友好-在操作筛选器中插入一个来创建SiteContext
实例,而不是使用服务定位器。啊,我想2)是我想要的。显然,DI友好的东西更好,所以我可以先试试,但是对于像这样的一些孤立的基础设施……嗯……这工作得相当好,尽管获取属性本身可能是一个有趣的难题。对于webapi过滤器,它是:Enumerable.Any(actionContext.ActionDescriptor.GetCustomAttributes());好吧,我明白你的意思了……但在第一个例子中,至少不会有同样的问题吗?过滤器在全局范围内解析,而不是在AutofacWebRequest
范围内解析,因此将是一个单例。如果属性本身只有一个实例,那么所有的生命周期都与服务定位器模式相同,不是吗?正如Erkan在评论中指出的,有两种方法可以解决这个问题1)使用Autofac接口而不是WebAPI接口2)使用依赖范围中的服务定位器(这是通过上下文传递的)。请参阅。可能还有第三个选项更为DI友好-在操作筛选器中插入一个来创建SiteContext
实例,而不是使用服务定位器。啊,我想2)是我想要的。显然,DI友好的东西更好,所以我可以先试试,但是对于像这样的一些孤立的基础设施……嗯……这工作得相当好,尽管获取属性本身可能是一个有趣的难题。对于webapi过滤器,它是:Enumerable.Any(actionContext.ActionDescriptor.GetCustomAttributes());
var csl = new AutofacServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => csl);
var user = await ServiceLocator.Current
.GetInstance<SiteContext>().FindAsync(id);
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.