我很可能在这里误解了什么,所以这里可能有一个简单的答案,但我现在很挠头。
我有一个类UnitOfWork实现IUnitOfWork(是的是的我知道)。工作单元的构造函数采用IPrincipalFactory。TResponder是图形的顶层,它接受一个IUnitOfWork。
我试图将ApplicationPrincipalFactory注册为生命周期范围内的特定实例…它依赖于传递给HandleAsync函数的一些属性。我正在做以下事情:
public async Task<TResponse> HandleAsync<TMessage, TResponse, TResponder>(TMessage message)
where TMessage : class
where TResponder : IRespondAsync<TMessage, TResponse>
{
using (var scope = this.BeginLifetimeScope(message))
{
var responder = scope.Resolve<TResponder>();
return await responder.Respond(message);
}
}
private ILifetimeScope BeginLifetimeScope<TMessage>(TMessage message)
{
var unwrapped = GetDomainContext(message);
var applicationPrincipalFactory = this.CreateApplicationPrincipalFactory(unwrapped);
var lifetime = this.container.BeginLifetimeScope(
r => r.RegisterInstance(applicationPrincipalFactory).As<IPrincipalFactory>());
return lifetime;
}
private ApplicationPrincipalFactory CreateApplicationPrincipalFactory(IDomainContext unwrapped)
{
var applicationPrincipalFactory =
new ApplicationPrincipalFactory(
unwrapped.Tenant,
unwrapped.ActingTenant,
unwrapped.Username);
return applicationPrincipalFactory;
}
根据我读过的所有内容,在BeginLifetimeScope(r =>)中定义依赖项应该覆盖父容器绑定,所以当我调用resolve时,它应该整齐地放在一起。
然而,我得到一个异常:None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Platform.Engine.Persistence.UnitOfWork' can be invoked with the available services and parameters: Cannot resolve parameter 'Platform.Engine.Security.IPrincipalFactory principalFactory' of constructor
我没有在这个方法之外的任何地方注册IPrincipalFactory。IUnitOfWork在外部作用域中定义如下:
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
我还尝试在子容器内重新定义工作单元注册,以防在外部容器而不是生命周期容器中注册引起问题:
var lifetime = this.container.BeginLifetimeScope(
r => r.RegisterInstance(applicationPrincipalFactory).As<IPrincipalFactory>());
var overrides = new ContainerBuilder();
overrides.RegisterType<UnitOfWork>().As<IUnitOfWork>();
overrides.Update(lifetime.ComponentRegistry);
return lifetime;
我不知道我错过了什么…有什么想法或建议吗?
在初始容器配置期间将工厂与其他类型注册。
builder.RegisterType<ApplicationPrincipalFactory>().As<IPrincipalFactory>();
然后在生命周期作用域中解析一个委托工厂,您可以将上下文传递给该工厂。
var factory = container.Resolve<Func<IDomainContext, IPrincipalFactory>>();
var instance = factory(context);
您也可以将三个string
参数添加到Func<>
签名中,但由于您已经有了一个很好的上下文对象,因此我将直接传递它。
最后,根据需要使用工厂。
instance.DoesSomethingButNotSureWhat();