Autofac参数传递到嵌套类型 [英] Autofac passing parameter to nested types
问题描述
我在我的WCF服务使用Autofac作为我的IoC。我有我想要的一个对象传递给嵌套类型的情况下(即一种不直接解决,但解决另一种类型时)。据我的理解,通过这个对象作为构造函数的参数是Autofac的首选方式。这里是这种情况的一个例子。
I am using Autofac as my IoC in my WCF service. I have a situation where I want to pass an object to a nested type (ie a type that is not resolved directly, but when resolving another type). As far as I understood, passing this object as a constructor parameter is the preferred way in Autofac. Here is an example of such a situation.
嵌套类型:
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服务操作内部的解析:
The resolving inside my WCF service operation:
var currentUser = GetUserFromServiceContext();
var bo = lifetimeScope.Resolve<SomeBusinessObject>();
如何,我应该在哪里当前用户传递给我的记录?我应该假定WCF操作必须知道,解决SomeBusinessObject需要先解决IEventLogger并通过一个实例解析解析SomeBusinessObject什么时候?事情是这样的(请原谅我,如果这也不行,那只是一个想法):
How and where should I pass the current user to my logger? Should I assume that the WCF operation has to know that resolving SomeBusinessObject requires to resolve IEventLogger first and pass a resolved instance when resolving SomeBusinessObject? Something like this (pardon me if this does not work, it is just an idea):
var currentUser = GetUserFromServiceContext();
var logger = lifetimeScope.Resolve<IEventLogger<SomeLogEventType>>(new NamedParameter("currentUser", currentUser));
var bo = lifetimeScope.Resolve<SomeBusinessObject>(new NamedParameter("logger", logger));
如果这是解决方案,如果该类型嵌套更深,会发生什么?没有那场失利至少有一些依赖注入的目的是什么?
If this is the solution, what happens if the type is nested deeper? Doesn't that defeat at least some of the purpose of dependency injection?
推荐答案
恕我直言,我认为您违反之一国际奥委会的一个组件的原则不应该需要了解的依赖它的依赖。你的情况,容器不知道 SomeBusinessObject
对用户
的依赖关系。
IMHO, I think you're violating one of the principles of IOC in that a component should not need to know about the dependencies of it's dependencies. In your case, the container doesn't know that SomeBusinessObject
has a dependency on User
.
话虽这么说,你可以利用Autofac的代表工厂的。你可以手动注册 Func键<使用者,SomeBusinessObject>
来隐藏客户端代码依赖链详细信息:
That being said, you may be able to leverage Autofac's Delegate Factories. You could manually register a Func<User, SomeBusinessObject>
to hide the dependency chain details from the client code:
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));
});
在您的客户端代码现在,你可以这样做:
Now in your client code, you can do:
var currentUser = GetUserFromServiceContext();
var sboFactory = lifetimeScope.Resolve<Func<User, SomeBusinessObject>>();
var bo = sboFactory(currentUser);
顺便说一句,我认为兰巴/ FUNC支持是什么使Autofac最好的IOC容器。如果你知道如何撰写funcs中,你可以做一些疯狂的强大的东西。
As an aside, I think the lamba/Func support is what makes Autofac the best IOC container. You can do some crazy powerful things if you know how to compose Funcs.
这篇关于Autofac参数传递到嵌套类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!