C# 将依赖项注入到";构造函数范围";-自动传真

C# 将依赖项注入到";构造函数范围";-自动传真,c#,autofac,C#,Autofac,我使用的是autofac 3.5.x,我的设置与此类似: public class ServiceA : IServiceA { } public class ServiceB : IServiceB { public ServiceB(IServiceA sa) { } } public class ServiceC : IServiceC { public ServiceC(IServiceA sa) { } } public class ServiceD : IServiceD { pub

我使用的是autofac 3.5.x,我的设置与此类似:

public class ServiceA : IServiceA { }
public class ServiceB : IServiceB { public ServiceB(IServiceA sa) { } }
public class ServiceC : IServiceC { public ServiceC(IServiceA sa) { } }
public class ServiceD : IServiceD { public ServiceD(IServiceA sa, IServiceB sb, IServiceC sc) {} }
在我的容器中,我有以下注册:

builder.RegisterType<ServiceA>.As<IServiceA>();
builder.RegisterType<ServiceB>.As<IServiceB>();
builder.RegisterType<ServiceC>.As<IServiceC>();
builder.RegisterType<ServiceD>.As<IServiceD>();
请注意,
GetServiceA()
方法仅用于说明我的观点

所以,是的,我想我正在寻找某种方法来告诉autofac,当它解析
IServiceD
时,它应该创建一个
ServiceA
的单例,但只针对
ServiceD
的构造函数的范围

现在,我使用autofacs支持代理工厂,并要求:

public ServiceD(IServiceA sa, Func<IServiceA, IServiceB> fb, Func<IServiceA, IServiceC> fc) : IServiceD
{
     var sb = fb(sa); // Manually inject the same instance of ServiceA
     var sc = fc(sa); // Manually inject the same instance of ServiceA

     // ServiceA is now the same instance
     sa.GetHashCode() == sb.GetServiceA().GetHashCode() == sc.GetServiceA().GetHashCode()
}
公共服务(IServiceA sa、Func fb、Func fc):IServiceD
{
var sb=fb(sa);//手动注入ServiceA的相同实例
var sc=fc(sa);//手动注入ServiceA的相同实例
//ServiceA现在是同一个实例
sa.GetHashCode()==sb.GetServiceA().GetHashCode()==sc.GetServiceA().GetHashCode()
}
这让我走了,但我有一种感觉,它可以做得更好-这就是为什么我现在转向专家


提前感谢。

InstancePerLifetimeScope可能适合您的需要。它允许您在每个生存期范围内拥有一个实例

builder.RegisterType<ServiceA>().As<IServiceA>().InstancePerLifetimeScope();
builder.RegisterType<ServiceB>().As<IServiceB>().InstancePerLifetimeScope();
builder.RegisterType<ServiceC>().As<IServiceC>().InstancePerLifetimeScope();
builder.RegisterType<ServiceD>().As<IServiceD>().InstancePerLifetimeScope();
如果无法创建新的
ILifetimeScope
,则可以使用
Owned
类型,这是一种轻量级的生存时间范围

using (Owned<IServiceD> ownedD = container.Resolve<Owned<IServiceD>>())
{
    IServiceD serviceD = ownedD.Value;                 
}

但它并不真正优雅

嗨,西里尔,很抱歉这么晚才接受你的回答。我感谢你的意见。你关于
InstancePerLifetimeScope()
的提示是我需要继续讨论的。谢谢
using (ILifetimeScope scope = container.BeginLifetimeScope())
{
    // only an instance of IServiceA will be created for this scope
    scope.Resolve<IServiceD>(); 
}
using (Owned<IServiceD> ownedD = container.Resolve<Owned<IServiceD>>())
{
    IServiceD serviceD = ownedD.Value;                 
}
builder.Register(ctx =>
{
    IServiceA serviceA = ctx.Resolve<IServiceA>();
    IServiceB serviceB = ctx.Resolve<IServiceB>(TypedParameter.From(serviceA));
    IServiceC serviceC = ctx.Resolve<IServiceC>(TypedParameter.From(serviceA));
    IServiceD serviceD = ctx.Resolve<IServiceD>(TypedParameter.From(serviceA), TypedParameter.From(serviceB), TypedParameter.From(serviceC));
    return serviceD;
}).As<IServiceD>();