C# Autofac生存期范围使用
我有一个.net微服务,它有一个服务a,它有一个InstancePerLifetimeScope。服务A被注入MessageService(单例服务) 通过这种方式,ServiceA正在成为任何调用它的线程的单例。 要实现InstancePerLifetimeScope,我需要:C# Autofac生存期范围使用,c#,.net,dependency-injection,autofac,C#,.net,Dependency Injection,Autofac,我有一个.net微服务,它有一个服务a,它有一个InstancePerLifetimeScope。服务A被注入MessageService(单例服务) 通过这种方式,ServiceA正在成为任何调用它的线程的单例。 要实现InstancePerLifetimeScope,我需要: public class MessageService { private readonly IContainer container; public MessageService(IContaine
public class MessageService
{
private readonly IContainer container;
public MessageService(IContainer container)
{
this.container = container;
}
public void ProcessItem(ItemClass item)
{
using (var scope = container.BeginLifetimeScope())
{
scope.Resolve<ServiceA>().Proccess(item);
}
}
}
公共类消息服务
{
专用只读IContainer容器;
公共消息服务(IContainer容器)
{
this.container=容器;
}
public void ProcessItem(ItemClass项)
{
使用(var scope=container.BeginLifetimeScope())
{
scope.Resolve().process(项);
}
}
}
这是好的做法吗?我听说这是服务定位器模式,被认为是反模式。另外,将容器作为可注入的直接传递到服务中并不是最好的做法
public class ServiceAFactory
{
private readonly IContainer container;
public ServiceAFactory(IContainer container)
{
this.container = container;
}
public IServiceA swapsService CreateService()
{
using (var scope = container.BeginLifetimeScope())
{
return scope.Resolve<IServiceA>();
}
}
}
公共类服务工厂
{
专用只读IContainer容器;
公共服务工厂(IContainer容器)
{
this.container=容器;
}
公共IServiceA SwapService CreateService()
{
使用(var scope=container.BeginLifetimeScope())
{
返回scope.Resolve();
}
}
}
禁止在应用程序代码中使用容器,并将其作为应用程序的一部分专门使用。有很多方法可以做到这一点,因此没有一个单一的答案,但通常您希望从业务代码中提取处理容器的代码
在您的简单示例中,类所做的一切似乎都与容器相关,因此这意味着将其完全移动到组合根。由于组合根应该是,而应用程序代码不应该依赖于组合根,这意味着其他代码不能调用MessageService
。通过引入一个抽象:IMessageService
,可以轻松优雅地解决这个问题:
public class MessageService : IMessageService
{
...
}
接口应该在应用程序级别定义,实现在合成根目录中
如果MessageService
也包含业务逻辑,事情就会变得更加复杂。您需要将业务逻辑与容器相关逻辑分开。以下是一些处理方法:
- 将容器内容从
提取到注入MessageService
的新服务中MessageService
- 将工厂用于
,该工厂允许创建新实例,但要验证工厂是否可用ServiceA
- 将容器逻辑移出
,移动到MessageService
周围的装饰器/代理中。这使得生活方式不匹配对ServiceA
和ServiceA
都不起作用。这涉及到围绕MessageService
定义一个抽象,让ServiceA
依赖于此,并从decorator的MessageService
方法中解析具体的过程
ServiceA
MessageService
。通过引入一个抽象:IMessageService
,可以轻松优雅地解决这个问题:
public class MessageService : IMessageService
{
...
}
接口应该在应用程序级别定义,实现在合成根目录中
如果MessageService
也包含业务逻辑,事情就会变得更加复杂。您需要将业务逻辑与容器相关逻辑分开。以下是一些处理方法:
- 将容器内容从
提取到注入MessageService
的新服务中MessageService
- 将工厂用于
,该工厂允许创建新实例,但要验证工厂是否可用ServiceA
- 将容器逻辑移出
,移动到MessageService
周围的装饰器/代理中。这使得生活方式不匹配对ServiceA
和ServiceA
都不起作用。这涉及到围绕MessageService
定义一个抽象,让ServiceA
依赖于此,并从decorator的MessageService
方法中解析具体的过程
ServiceA
IContainer
使用Autofac,您可以将工厂Func
(而不是ServiceA
)注入MessageService
。只要您在容器中注册了ServiceA
,Autofac就会自动为您生成这样一个工厂函数
来自Autofac关于以下各项的文档:
“使用自动生成的工厂可以让您有效地调用[Resolve()
],而无需将组件绑定到Autofac。[…]
“使用此关系类型尊重生存期范围。如果将[B
]注册为InstancePerDependency()
并多次调用Func
,每次都会得到一个新实例。但是,如果将[B
]注册为SingleInstance()
,并多次调用Func
解析对象,则每次都会得到相同的对象实例。”
(我的轻微改动或遗漏放在方括号内。)我同意,你不应将你的申请与