我在我的WCF服务中使用Autofac作为我的IoC。我有一种情况,我想将一个对象传递给嵌套类型(即一种未直接解析的类型,但在解析另一种类型时)。据我所知,将此对象作为构造函数参数传递是Autofac中的首选方法。以下是这种情况的一个例子。
嵌套类型:
public class EventLogger<T> : IEventLogger<T>
{
public EventLogger(IRepository<T> repository, User currentUser) { ... }
}
我实际上试图解决的类型:
public class SomeBusinessObject
{
public SomeBusinessObject(IEventLogger<SomeLogEventType> logger, ...) { ... }
}
注册:
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
builder.RegisterGeneric(typeof(EventLogger<>)).As(typeof(IEventLogger<>));
builder.RegisterType<SomeBusinessObject>();
解析我的WCF服务操作:
var currentUser = GetUserFromServiceContext();
var bo = lifetimeScope.Resolve<SomeBusinessObject>();
我应该如何以及在何处将当前用户传递给我的记录器?我是否应该假设WCF操作必须知道解析SomeBusinessObject需要首先解析IEventLogger并在解析SomeBusinessObject时传递已解析的实例?这样的事情(原谅我,如果这不起作用,这只是一个想法):
var currentUser = GetUserFromServiceContext();
var logger = lifetimeScope.Resolve<IEventLogger<SomeLogEventType>>(new NamedParameter("currentUser", currentUser));
var bo = lifetimeScope.Resolve<SomeBusinessObject>(new NamedParameter("logger", logger));
如果这是解决方案,如果类型嵌套得更深,会发生什么?难道这至少打败了依赖注入的一些目的吗?
答案 0 :(得分:6)
SomeBusinessObject
依赖User
。
话虽如此,您可以利用Autofac的Delegate Factories。您可以手动注册Func<User, SomeBusinessObject>
以隐藏客户端代码中的依赖关系链详细信息:
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 currentUser = GetUserFromServiceContext();
var sboFactory = lifetimeScope.Resolve<Func<User, SomeBusinessObject>>();
var bo = sboFactory(currentUser);
另外,我认为lamba / Func支持是使Autofac成为最佳IOC容器的原因。如果你知道如何编写Funcs,你可以做一些疯狂的强大事情。