C# Autofac将参数传递给嵌套类型
我在WCF服务中使用Autofac作为我的IoC。在这种情况下,我希望将对象传递给嵌套类型(即未直接解析的类型,但在解析其他类型时)。据我所知,将此对象作为构造函数参数传递是Autofac中的首选方式。以下是这种情况的一个例子 嵌套类型:C# Autofac将参数传递给嵌套类型,c#,ioc-container,autofac,C#,Ioc Container,Autofac,我在WCF服务中使用Autofac作为我的IoC。在这种情况下,我希望将对象传递给嵌套类型(即未直接解析的类型,但在解析其他类型时)。据我所知,将此对象作为构造函数参数传递是Autofac中的首选方式。以下是这种情况的一个例子 嵌套类型: public class EventLogger<T> : IEventLogger<T> { public EventLogger(IRepository<T> repository, User currentUs
public class EventLogger<T> : IEventLogger<T>
{
public EventLogger(IRepository<T> repository, User currentUser) { ... }
}
public类事件记录器:IEventLogger
{
公共事件记录器(IRepository存储库,用户currentUser){…}
}
我实际尝试解析的类型:
public class SomeBusinessObject
{
public SomeBusinessObject(IEventLogger<SomeLogEventType> logger, ...) { ... }
}
公共类SomeBusinessObject
{
公共SomeBusinessObject(IEventLogger记录器,…{…}
}
注册:
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
builder.RegisterGeneric(typeof(EventLogger<>)).As(typeof(IEventLogger<>));
builder.RegisterType<SomeBusinessObject>();
var builder=newcontainerbuilder();
builder.RegisterGeneric(typeof(Repository)).As(typeof(IRepository));
builder.RegisterGeneric(typeof(EventLogger)).As(typeof(IEventLogger));
RegisterType();
“我的WCF服务”操作中的解决方案:
var currentUser = GetUserFromServiceContext();
var bo = lifetimeScope.Resolve<SomeBusinessObject>();
var currentUser=GetUserFromServiceContext();
var bo=lifetimeScope.Resolve();
如何以及在何处将当前用户传递到日志记录器?我是否应该假设WCF操作必须知道解析SomeBusinessObject需要首先解析IEventLogger,并在解析SomeBusinessObject时传递已解析的实例?类似这样的事情(如果这不起作用,请原谅,这只是一个想法):
var currentUser=GetUserFromServiceContext();
var logger=lifetimeScope.Resolve(新名称参数(“currentUser”,currentUser));
var bo=lifetimeScope.Resolve(新名称参数(“logger”,logger));
如果这是解决方案,那么如果类型嵌套得更深会发生什么?这难道至少有一点不符合依赖注入的目的吗?我认为您违反了IOC的原则之一,组件不需要知道其依赖项的依赖项。在您的情况下,容器不知道
SomeBusinessObject
依赖于User
也就是说,您可以利用Autofac的。您可以手动注册Func
,以对客户端代码隐藏依赖项链详细信息:
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
builder.RegisterGeneric(typeof(EventLogger<>)).As(typeof(IEventLogger<>));
builder.RegisterType<SomeBusinessObject>();
builder.Register<Func<User, SomeBusinessObject>>(c => {
// Autofac should be able to resolve these Func<> automatically:
var loggerFactory = c.Resolve<Func<User, IEventLogger<SomeLogEventType>>>();
var sboFactory = c.Resolve<Func<IEventLogger<SomeLogEventType>, SomeBusinessObject>>();
// Now we can chain the Funcs:
return u => sboFactory(loggerFactory(u));
});
var builder=newcontainerbuilder();
builder.RegisterGeneric(typeof(Repository)).As(typeof(IRepository));
builder.RegisterGeneric(typeof(EventLogger)).As(typeof(IEventLogger));
RegisterType();
builder.Register(c=>{
//Autofac应能够自动解析这些函数:
var loggerFactory=c.Resolve();
var sboFactory=c.Resolve();
//现在我们可以链接函数:
返回u=>sbofacory(loggerFactory(u));
});
现在,在客户端代码中,您可以执行以下操作:
var currentUser = GetUserFromServiceContext();
var sboFactory = lifetimeScope.Resolve<Func<User, SomeBusinessObject>>();
var bo = sboFactory(currentUser);
var currentUser=GetUserFromServiceContext();
var sboFactory=lifetimeScope.Resolve();
var bo=备用办公室(当前用户);
另外,我认为对lamba/Func的支持使Autofac成为最好的IOC容器。如果你知道如何编写Funcs,你可以做一些非常强大的事情。谢谢你的回答。你能详细说明我违反国际奥委会原则的事实吗?我同意你的看法,我的最后一个解决办法是,但我不知道为什么你的答案也不一样。我的意思是,您的回答还表明,要构建某个BusinessObject,您需要知道它需要一个用户。我的回答也是:)这是一个解决办法。但是如果我必须按设计使用对象,我会这样做,至少尽可能最好地封装依赖关系。好吧,我明白了!:-)如果你不得不改变物体的设计呢?;-)我对国际奥委会很陌生,我还没有真正了解我的观点……你可以考虑是否有一种方式来登记类型<代码>用户< />代码。我在
builder.Register(c=>HttpContext.Current.User)中使用IPrincipal
执行类似的操作代码>我明白了。这意味着,每当我有一个用户
作为参数时,它都会被解析成这样?
var currentUser = GetUserFromServiceContext();
var sboFactory = lifetimeScope.Resolve<Func<User, SomeBusinessObject>>();
var bo = sboFactory(currentUser);