Autofac中的AsImplementedInterfaces()

在项目开发中,遇到一个问题,是这样的,我们有一个接口IConfiguration

public interface IConfiguration 
{        
        string DefaultValue { get; }

        int Order { get; }
}

另外有一个接口ITelemetryConfiguration继承它

 public interface ITelemetryConfiguration : IConfiguration
 {
         string TelemetryValue {get; }
 }

现在有2个类,一个是LogLevel类,它继承IConfiguration接口. 另一个是TelemetrySupport类,它继承ITelemetryConfiguration接口。 如下

public class LogLevel : IConfiguration
{
   private string logvalue;

   public string DefaultValue 
   {
       get {return logvalue;}
       set {logvalue = value;}    
   }
   

   public int Order
   {
       get {return 1;}
   }

}
public class TelemetrySupport : ITelemetryConfiguration
{
     public string DefaultValue
     {
            get { return "Enable"; }
      }

      
     public string TelemetryValue
        {
            get; set;
        }

        public int LoadOrder
        {
            get
            {
                return 2;
            }
        }


}

 

在系统启动时用Autofac写的依赖注入中,我们原来是这样写的

using Autofac;
using Module = Autofac.Module;

public class IoCModule : Module
{
    
    protected override void Load(ContainerBuilder builder)
    {
          
         builder.RegisterType<LogLevel>().As<IConfiguration>().SingleInstance(); // 请求IConfiguration返回的是接口实现类LogLevel的实例
         builder.RegisterType<TelemetrySupport>().As<ITelemetryConfiguration>().SingleInstance(); // 请求ITelemetryConfiguration返回的是接口实现类TelemetrySupport的实例


    }



}

 然后在程序中,我们Load进来一个IEnumerable<IConfiguration>, 我们本来是期望这里面包括LogLevel和TelemetrySupport的信息。

public class ConfigurationLoader
{
   private readonly IEnumerable<IConfiguration> configurations;
   public ConfigurationLoader(IEnumerable<IConfiguration> configurations)
   {
        this.configurations = configurations;
   }

  public void LoadConfiguration()
  {
try
{
  foreach (var databaseConfig in configurations.OrderBy(x => x.Order)) // 我们预期的目的是期望从这个configurations里面里面读取出LogLevel和TelemetrySupport,但在实际debug时,发现里面只包括Loglevel,没有TelemetrySupport
{
......
}

}
catch(Exception e)
{
.......
} } }

 问题就是出现在上面,我们在上面这个ConfigurationLoader类中,通过Autofac的依赖注入,把IEnumerable<IConfiguration> configurations注入进来了. 通过上面我们看到LogLevel, TelemetrySupport都是继承这个IConfiguration接口的(TelemetrySupport实现了ITelemetryConfiguration接口,而ITelemetryConfiguration接口又继承自IConfiguration接口), 这时,我理所当然的以为在上面这个类的IEnumerable<IConfiguration>会包含LogLevel和TelemetrySupport的信息,但实际debug时,发现只包含LogLevel,而没有TelemetrySupport。 问题出在哪里呢?

 

回到上面IocModule进行依赖注入的地方,依赖注入是这么写的

builder.RegisterType<LogLevel>().As<IConfiguration>().SingleInstance();    =>   请求IConfiguration返回的是接口实现类LogLevel的实例
builder.RegisterType<TelemetrySupport>().As<ITelemetryConfiguration>().SingleInstance();  => 请求ITelemetryConfiguration返回的是接口实现类TelemetrySupport的实例

 

我们看到,LogLevel, 是请求IConfiguration接口时,返回的是LogLevel的实例 = > 所以上面的IEnumerable<IConfiguration> configurations会包括它

而TelemetrySupport, 是请求ITelemetryConfiguration返回的是接口实现类TelemetrySupport的实例。 而请求IConfiguration并不会返回TelemetrySupport的实例  =>  所以上面的IEnumerable<IConfiguration> configurations不包括它

 

那么,应该怎么解决呢?

应该把builder.RegisterType<TelemetrySupport>().As<ITelemetryConfiguration>().SingleInstance() => 改为 builder.RegisterType<TelemetrySupport>().AsImplementedInterfaces().SingleInstance() 

builder.RegisterType<TelemetrySupport>().AsImplementedInterfaces().SingleInstance()   => 用这个AsImplementedInterfaces 表示 请求TelemetrySupport实现的任何接口(包括ITelemetryConfiguration和IConfiguration接口),都会返回TelemetrySupport的实例

 

改完后如下

using Autofac;
using Module = Autofac.Module;

public class IoCModule : Module
{
    
    protected override void Load(ContainerBuilder builder)
    {
          
         builder.RegisterType<LogLevel>().As<IConfiguration>().SingleInstance(); // 请求IConfiguration返回的是接口实现类LogLevel的实例
         builder.RegisterType<TelemetrySupport>().AsImplementedInterfaces().SingleInstance(); // 请求TelemetrySupport实现的任何接口,都会返回实现类TelemetrySupport的实例


    }



}

这样,上面的IEnumerable<IConfiguration> configurations就会包含LogLevel 和 TelemetrySupport了

 

 

 


 

 


posted on 2023-01-31 11:02  新西兰程序员  阅读(442)  评论(0编辑  收藏  举报