我正在编写MVC UI包装器,重用使用Autofac for DI为桌面版写下的旧版核心库。我面临的问题是,核心库正在使用Lifetime范围,我无法在MVC需要InstancePerRequest时进行更改。
所以,在MVC中,如果我为InstancePerRequest范围注册我的服务,它们会在请求完成之前由核心库处理。它使得MVC应用程序不满意 我尝试将LifeTimeScope用于MVC应用程序中的所有服务。由于生命周期范围比请求生命周期短,因此它似乎适用于MVC。
这种方法有什么缺点吗?
注意:在遗留代码中,所有时间服务都是手动解析的,而不是通过构造函数注入。像:
using (var scope = IocContainer.BeginLifetimeScope())
{
var service = scope.Resolve<IMyService>();
return service.FindAll();
}
答案 0 :(得分:0)
MVC将与InstancePerLifetimeScope
一起使用服务as noted in the documentation about sharing registrations across apps that have and apps that don't have request scopes。
我认为在创建自己的生命周期范围的方法中可能存在两个陷阱。你是否可以和他们一起生活是非常具体的应用程序,所以你必须自己判断。
问题1:早期处置
在您的示例中,您显示正在解决的工厂或服务IMyService
,正在做一些工作,并返回该工作。在using
语句结束时,拥有的生命周期范围正在处理中。这意味着IMyService
将被处置(如果它是IDisposable
),并且IMyService
所需的任何依赖关系也将被处置。对于像数据库上下文或连接这样的事情,很可能意味着返回值变为无效,因为您将无法更新值或读取已处理连接的其他数据。
问题2:单身人士/分享问题
有时使用生命周期范围来隔离需要共享上下文的工作单元或组件集。例如,在MVC中,您只有一个控制器实例用于整个请求 - 无论您解析控制器对象多少次,对于该请求,它都将是同一个实例。您可能会看到与数据库连接类似的事情 - 从为整个请求生命周期分配的池中的一个连接。
通过创建自己的生命周期范围,您还可以创建一种逻辑工作单元。 IMyService
的任何依赖项将不与MVC请求的其余部分共享。实际上,它更像是微小的生命周期范围是它自己的请求或它自己的工作单元。没有重叠。
一般性决议
如doc I linked to earlier中所述,如果需要在MVC和非MVC上下文中使用,请将内容注册为InstancePerLifetimeScope
,并且只需让MVC请求语义处理调整范围和处理范围。可能的。
如果这不起作用,则由您和您的应用代码决定您是否可以解决此处的问题或者您是否需要解决这些问题。如果您需要解决这些问题,那么它也将是应用程序特定的,因此没有“指导”提供 - 您可以自行解决这个问题。