在构造函数注入期间解析为父接口

时间:2019-06-14 04:38:50

标签: autofac

这涉及到autofac和c#。我有一个从父接口派生的接口:

public interface IJ4JLogger<out TCalling>
{
}

public interface IJ4JSmsLogger<out TCalling> : IJ4JLogger<TCalling>
{
}

某些类依赖于在构造过程中被提供给父接口的实例:

public FileHistoryConfiguration( IJ4JLogger<FileHistoryConfiguration> histLogger, IJ4JLogger<FileHistoryService> svcLogger )
{
}

但是如果我在autofac中注册这样的类型:

builder.RegisterGeneric( typeof(J4JSmsLogger<>) )
    .As(typeof(IJ4JSmsLogger<>))
    .SingleInstance();

其中J4JSmsLogger <>是实现IJ4JSmsLogger <>的类,则此调用失败,并显示一个错误,即找不到为提供IJ4JLogger <>接口而注册的任何内容:

_fhConfig = _svcProvider.GetRequiredService<IFileHistoryConfiguration>();

我可以通过更改J4JSmsLogger <>注册中的As <>子句以将其视为IJ4JLogger <>实例来解决该问题,然后在需要时将解析该接口的结果转换为IJ4JSmsLogger <>子界面的额外功能。

但是我不明白为什么我必须这样做。在用autofac注册类型期间,我是否还需要采取其他步骤,以便实现子接口的对象可以满足父接口的需要?

更清洁的解决方法

阅读有关autofac的更多信息,我学到了一些新东西:您可以根据需要定义尽可能多的As <>()子句(包括AsSelf())。因此,将我的autofac配置更改为:

builder.RegisterGeneric( typeof(J4JSmsLogger<>) )
    .As(typeof(IJ4JSmsLogger<>))
    .As(typeof(IJ4JLogger<>))
    .SingleInstance();

与不断投射已解决的实例相比,提供了更清洁的解决方案。

不过,我不会将其作为答案提交,因为我很好奇为什么autofac不会自动进行这种向下转换,以及是否有其他DI框架也可以这样做。

1 个答案:

答案 0 :(得分:1)

Autofac不会那样为您转换为基本类型。通常假定接线正确。如果没有,您可能会遇到一些实际的问题,例如某人具有类似...的构造函数。

public class BadTimes
{
  public BadTimes(object input) { }
}

它放在哪个对象中?一切都变成对象。

但是,您始终可以将其注册为两种类型并称为一天:

builder.RegisterGeneric(typeof(J4JSmsLogger<>))
    .As(typeof(IJ4JSmsLogger<>))
    .As(typeof(IJ4JLogger<>))
    .SingleInstance();