c# - Autofac 将参数传递给嵌套类型

标签 c# ioc-container autofac

我在 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));

如果这是解决方案,如果类型嵌套得更深会发生什么?这不会至少破坏依赖注入(inject)的某些目的吗?

最佳答案

恕我直言,我认为您违反了 IOC 的一项原则,即组件不需要了解其依赖项的依赖项。在您的情况下,容器不知道 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 容器。如果您知道如何编写 Func,您可以做一些疯狂而强大的事情。

关于c# - Autofac 将参数传递给嵌套类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5741761/

相关文章:

c# - 在 AWS Lambda serverless.template 文件中设置 EndpointConfiguration

ioc-container - 为 asp.net webapi 选择 IoC 容器

inversion-of-control - 从源代码构建 Autofac

c# - System.Threading.Timer 回调中的关键部分

c# - Elasticsearch按日期查询返回错误结果

c# - 需要关闭所有正在运行的应用程序而不使用从 c# 应用程序注销的 Windows

c# - 服务定位器比依赖注入(inject)更容易使用?

windows-services - Autofac - 如何处理根生命周期?

c# - 具有多个数据库的存储库模式

asp.net-mvc-3 - 带有 Autofac 简单网格绑定(bind)的 DevExpress