这涉及到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框架也可以这样做。
答案 0 :(得分:1)
Autofac不会那样为您转换为基本类型。通常假定接线正确。如果没有,您可能会遇到一些实际的问题,例如某人具有类似...的构造函数。
public class BadTimes
{
public BadTimes(object input) { }
}
它放在哪个对象中?一切都变成对象。
但是,您始终可以将其注册为两种类型并称为一天:
builder.RegisterGeneric(typeof(J4JSmsLogger<>))
.As(typeof(IJ4JSmsLogger<>))
.As(typeof(IJ4JLogger<>))
.SingleInstance();