.NET Core 如何整合第三方的Autofac


  Auto 如何和和.net core 内置依赖注入框架整合起来?

   在.net core中有一个Hosting组件,主机/托管 ,Hosting 里面托管了 需要在后台长时间运行的服务,一个ASP.net core 应用其实就是一项由Hosting托管的服务。依赖程序进程。

  Hosting 采用依赖注入的方式来获取托管应用所需的服务。所以我们要把第三方的依赖注入框架整合起来就要使用这个东西。

   要整合Autofac:

    1.安装响应的nuget 包  Autofac(本体) 和 Autofac.Extensions.DependencyInjection (拓展)

     2.例子:

public static class Sample01
{
  public interface IAccount{ }
  public interface IMessage{ }
  public interface ITool{ }

  public class Base
  {
    public Base()
  {
   Console.WriteLine($"Created:{GetType().Name}");
   } 

  public class Account:Base, IAccount{}
  public class Message:Base, IMessage{}
  public class Tool:Base, ITool{}

  public static void Run()
 {
   var serviceCollection = new ServiceCollection()
   .AddTransient()
   .AddTransient();

   var containerBuilder = new ContainerBuilder();

   containerBuilder.Populate(serviceCollection);

   containerBuilder.RegisterType().As();
   //创建容器
    var container = containerBuilder.Build();
   //创建服务提供对象
   IServiceProvider provider = new AutofacServiceProvider(container);

    provider.GetService();
  }
}

演变示例

 public static class Sample02
 {
   public interface IAccount{ }
   public interface IMessage{ }
   public interface ITool{ }

  public interface ITest
  {
  public IMessage Message { get; set; }
  }


  public class Base
  {
  public Base()
   {
  Console.WriteLine($"Created:{GetType().Name}");
 }

 }

  public class Account:Base, IAccount{}
  public class Message:Base, IMessage{}

  public class Tool : Base, ITool { }

 public class Test: ITest
 {
  public IMessage Message { get; set; }

  public Test(IAccount account, ITool tool)
 {
  Console.WriteLine($"Ctor:Test(IAccount, ITool)");
  }
 }

  public static void Run()
 {
  var serviceCollection = new ServiceCollection()
  .AddTransient();

  var containerBuilder = new ContainerBuilder();

  containerBuilder.Populate(serviceCollection);
  // 属性注入
   containerBuilder.RegisterType().As().PropertiesAutowired();
  // 程序集注册
   containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
  // 筛选基类为Base
   .Where(t => t.BaseType == typeof(Base))
   // 暴露第一个接口
  .As(t => t.GetInterfaces()[0])
  // 生命周期模式为Scope
  .InstancePerLifetimeScope();

  var container = containerBuilder.Build();
  IServiceProvider provider = new AutofacServiceProvider(container);

  Debug.Assert(provider.GetService() is Account);
  Debug.Assert(provider.GetService() is Message);
  Debug.Assert(provider.GetService() is Tool);

  var test = provider.GetService();
  Debug.Assert(test.Message is Message);
   Console.Read();
  }
 }

  上面是在.net core 一般处理程序中的演示,下面样式.net core 应用程序的情况

   因为内置默认有的DI 所以不需要引用任何程序集 ,而使用autofac是第三方是需要引用   Autofac 和 Autofac.Extensions.DependencyInjection 的nuget包

   注意asp.net  core 不会通过容器来创建控制器的实例,但是会通过容器来获取控制器的构造函数 所需要的实例!

   项目结构查看:

   

   

   

   

   autofac 模块化实现:

    

     Startup.cs 代码:

public class Startup
{
   public Startup(IConfiguration configuration)
  {
   Configuration = configuration;
   }

   public IConfiguration Configuration { get; }

   public void ConfigureServices(IServiceCollection services)
  {
  //加这个是将控制器所谓服务注入,默认注入集合中
  services.AddControllers().AddControllersAsServices();
  //使用内置的DI
   services.AddTransient();
   services.AddTransient();
   }

  ///


  /// 如果使用第三方的Autofac时要定义这个方法
  ///

  ///
  public void ConfigureContainer(ContainerBuilder builder)
  {
    // var assembly = Assembly.GetEntryAssembly();
   //builder.RegisterAssemblyTypes(Assembly.GetEntryAssembly())
   // //暴露第一个接口
   // .As(t => t.GetInterfaces()[0])
   // //生命周期模式设置为作用域
   // .InstancePerLifetimeScope();


   ///这是为了实现控制器的属性注入
   builder.RegisterType().PropertiesAutowired();

   //var containerBaseType = typeof(ControllerBase);
   //builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
   //.Where(t => t.IsAssignableFrom(t) && t != containerBaseType)
   //.PropertiesAutowired();

   //(服务多的时候用模块化)批量实现控制器的属性注入
   builder.RegisterModule();
  }


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
   if (env.IsDevelopment())
   {
  app.UseDeveloperExceptionPage();
  }

   app.UseHttpsRedirection();

  app.UseRouting();

  app.UseAuthorization();

   app.UseEndpoints(endpoints =>
   {
    endpoints.MapControllers();
   });
   }
  }
}

   使用 Scrutor 组件实现DI:

  Startup.cs 代码:

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
//加这个是将控制器所谓服务注入,默认注入集合中
services.AddControllers().AddControllersAsServices();
//使用内置的DI
services.AddTransient();
services.AddTransient();
}

///


/// 如果使用第三方的Autofac时要定义这个方法
///

///
public void ConfigureContainer(ContainerBuilder builder)
{
// var assembly = Assembly.GetEntryAssembly();
//builder.RegisterAssemblyTypes(Assembly.GetEntryAssembly())
// //暴露第一个接口
// .As(t => t.GetInterfaces()[0])
// //生命周期模式设置为作用域
// .InstancePerLifetimeScope();


///这是为了实现控制器的属性注入
builder.RegisterType().PropertiesAutowired();

//var containerBaseType = typeof(ControllerBase);
//builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
//.Where(t => t.IsAssignableFrom(t) && t != containerBaseType)
//.PropertiesAutowired();

//(服务多的时候用模块化)批量实现控制器的属性注入
builder.RegisterModule();
}


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}