我在我的 Web API 应用程序中使用AutoFac (使用发布此问题时可用的最新版本)。我的服务依赖项之一是AuditService
使用按DbContext
类型的实例(我们现在称之为MyDbContext
)。我的大部分服务和MyDbContext
类型都是使用InstancePerRequest注册的。对于我来说AuditService
,我想破例,我总是想注入一个拥有的(新的)我的MyDbContext
.
问题:使用AutoFac注册,我如何注册我AuditService
的,以便它总是获得一个拥有的(新的)实例MyDbContext
?
什么可以工作:
MyDbContext
我可以在构造函数中硬编码创建,AuditService
从而一起绕过 AutoFac。- 我可以使用PropertyInjection 或 MethodInjection
MyDbContext
并在 Life Time 事件OnActivating中提供一个新实例 - 我可以定义第二个接口
MyDbContext
并提供第二个注册和使用InstancePerOwned
。
我是否必须选择上述选项之一(如果是这样,我会倾向于 3)还是我错过了一些简单的东西?有没有办法在我的注册码中定义我想要的内容?
// registration called in web api startup code
public void RegisterAutofac(ContainerBuilder builder)
{
builder.RegisterType<MyDbContext>()
.As<IMyDbContext>()
.InstancePerRequest();
builder.RegisterType<BusinessService>()
.As<IBusinessService>()
.InstancePerRequest();
builder.RegisterType<AuditService>()
.As<IAuditService>()
.InstancePerRequest();
}
public class AuditService
{
// expects an isolated instance on this request
private readonly IMyDbContext _dbContext;
public AuditService(IMyDbContext dbContext)
{
_dbContext = dbContext;
}
}
public class BusinessService
{
// expect a shared IMyDbContext instance across the request
private readonly IMyDbContext _dbContext;
public BusinessService(IMyDbContext dbContext)
{
_dbContext = dbContext;
}
}
使用 InstancePerOwned 的解决方案尝试
这会导致异常
builder.RegisterType<MyDbContext>()
.As<IMyDbContext>()
.InstancePerRequest()
.InstancePerOwned<AuditService>();
Autofac.Core.DependencyResolutionException:“从请求实例的范围内看不到带有匹配'AuditService'标签的范围。如果您在执行Web应用程序期间看到这一点,通常表明组件注册为per-HTTP请求由 SingleInstance() 组件(或类似场景)请求。在 Web 集成下,始终从依赖解析器或请求生命周期范围请求依赖,而不是从容器本身。
at Autofac.Core.Lifetime.MatchingScopeLifetime.FindScope(ISharingLifetimeScope mostNestedVisibleScope) at Autofac.Core.Resolving.InstanceLookup..ctor(IComponentRegistration registration, IResolveOperation context, ISharingLifetimeScope mostNestedVisibleScope, IEnumerable`1 parameter
我尝试颠倒InstancePerOwned
andInstancePerRequest
调用的顺序,但这似乎没有效果,同一个MyDbContext
实例被重复用于同一个请求中的BusinessService
andAuditService
实例。这是用object.ReferenceEquals
from in an测试的,ApiController
并在两个实例的_dbContext
字段中传递。
builder.RegisterType<MyDbContext>()
.As<IMyDbContext>()
.InstancePerOwned<AuditService>()
.InstancePerRequest();