Autofac将参数传递给嵌套类型

我在我的WCF服务中使用Autofac作为我的IoC。 我有一种情况,我想将一个对象传递给嵌套类型(即一种未直接解析的类型,但在解析另一种类型时)。 据我所知,将此对象作为构造函数参数传递是Autofac中的首选方法。 以下是这种情况的一个例子。

嵌套类型:

public class EventLogger : IEventLogger { public EventLogger(IRepository repository, User currentUser) { ... } } 

我实际上试图解决的类型:

 public class SomeBusinessObject { public SomeBusinessObject(IEventLogger logger, ...) { ... } } 

注册:

 var builder = new ContainerBuilder(); builder.RegisterGeneric(typeof(Repository)).As(typeof(IRepository)); builder.RegisterGeneric(typeof(EventLogger)).As(typeof(IEventLogger)); builder.RegisterType(); 

解析我的WCF服务操作:

 var currentUser = GetUserFromServiceContext(); var bo = lifetimeScope.Resolve(); 

我应该如何以及在何处将当前用户传递给我的记录器? 我是否应该假设WCF操作必须知道解析SomeBusinessObject需要首先解析IEventLogger并在解析SomeBusinessObject时传递已解析的实例? 这样的事情(原谅我,如果这不起作用,这只是一个想法):

 var currentUser = GetUserFromServiceContext(); var logger = lifetimeScope.Resolve<IEventLogger>(new NamedParameter("currentUser", currentUser)); var bo = lifetimeScope.Resolve(new NamedParameter("logger", logger)); 

如果这是解决方案,如果类型嵌套得更深,会发生什么? 难道这至少打败了dependency injection的一些目的吗?

恕我直言,我认为你违反了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(); builder.Register>(c => { // Autofac should be able to resolve these Func<> automatically: var loggerFactory = c.Resolve>>(); var sboFactory = c.Resolve, SomeBusinessObject>>(); // Now we can chain the Funcs: return u => sboFactory(loggerFactory(u)); }); 

现在在您的客户端代码中,您可以:

 var currentUser = GetUserFromServiceContext(); var sboFactory = lifetimeScope.Resolve>(); var bo = sboFactory(currentUser); 

另外,我认为lamba / Func支持是使Autofac成为最佳IOC容器的原因。 如果你知道如何编写Func,你可以做一些疯狂的强大的事情。