加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 17:13:24 所属栏目:百科 来源:网络整理
导读:我在我的WCF服务中使用Autofac作为我的IoC.我有一种情况,我想将一个对象传递给嵌套类型(即一种未直接解析的类型,但在解析另一种类型时).据我所知,将此对象作为构造函数参数传递是Autofac中的首选方法.以下是这种情况的一个例子. 嵌套类型: public class Eve
我在我的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));

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

解决方法

恕我直言,我认为你违反了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,你可以做一些疯狂的强大的事情.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读