.net 6.0 依赖注入容器使用autofac 源码分析过程

一、 netCore 6.0 的源码下载

  地址如下:https://github.com/dotnet/   

  可以用GIT 下载 :git clone --recursive https://github.com/dotnet/aspnetcore.git

  内容如下图所示:

  

 

 

 其中aspnetcore 和runtime 是源码的主要工程。

  

二、netCore 6.0 的引用源码地址

  引用的地址:https://github.com/dotnet/runtime/tree/main/src/libraries

三、webapi 项目创建

  var builder = WebApplication.CreateBuilder(args);

  源码如下:

  /// <summary>
  /// Initializes a new instance of the <see cref="WebApplicationBuilder"/> class with preconfigured defaults.
  /// </summary>
  /// <param name="args">Command line arguments</param>
  /// <returns>The <see cref="WebApplicationBuilder"/>.</returns>
  public static WebApplicationBuilder CreateBuilder(string[] args) =>
      new(new() { Args = args });

  用了一个静态函数来创建 WebApplicationBuilder 对象;

  实例化过程源码如下:

  internal WebApplicationBuilder(WebApplicationOptions options, Action<IHostBuilder>? configureDefaults = null)
  {
    var configuration = new ConfigurationManager();

    configuration.AddEnvironmentVariables(prefix: "ASPNETCORE_");

    _hostApplicationBuilder = new HostApplicationBuilder(new HostApplicationBuilderSettings
    {
      Args = options.Args,
      ApplicationName = options.ApplicationName,
      EnvironmentName = options.EnvironmentName,
      ContentRootPath = options.ContentRootPath,
      Configuration = configuration,
    });

    // Set WebRootPath if necessary
    if (options.WebRootPath is not null)
    {
      Configuration.AddInMemoryCollection(new[]
      {
        new KeyValuePair<string, string?>(WebHostDefaults.WebRootKey, options.WebRootPath),
      });
    }

    // Run methods to configure web host defaults early to populate services
    var bootstrapHostBuilder = new BootstrapHostBuilder(_hostApplicationBuilder);

    // This is for testing purposes
    configureDefaults?.Invoke(bootstrapHostBuilder);

    bootstrapHostBuilder.ConfigureWebHostDefaults(webHostBuilder =>
    {
      // Runs inline.
      webHostBuilder.Configure(ConfigureApplication);

      webHostBuilder.UseSetting(WebHostDefaults.ApplicationKey, _hostApplicationBuilder.Environment.ApplicationName ?? "");
      webHostBuilder.UseSetting(WebHostDefaults.PreventHostingStartupKey, Configuration[WebHostDefaults.PreventHostingStartupKey]);
      webHostBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, Configuration[WebHostDefaults.HostingStartupAssembliesKey]);
      webHostBuilder.UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey,           Configuration[WebHostDefaults.HostingStartupExcludeAssembliesKey]);
    },
    options =>
    {
        // We've already applied "ASPNETCORE_" environment variables to hosting config
        options.SuppressEnvironmentConfiguration = true;
    });

    // This applies the config from ConfigureWebHostDefaults
    // Grab the GenericWebHostService ServiceDescriptor so we can append it after any user-added IHostedServices during Build();
    _genericWebHostServiceDescriptor = bootstrapHostBuilder.RunDefaultCallbacks();

    // Grab the WebHostBuilderContext from the property bag to use in the ConfigureWebHostBuilder. Then
    // grab the IWebHostEnvironment from the webHostContext. This also matches the instance in the IServiceCollection.
    var webHostContext = (WebHostBuilderContext)bootstrapHostBuilder.Properties[typeof(WebHostBuilderContext)];
    Environment = webHostContext.HostingEnvironment;

    Host = new ConfigureHostBuilder(bootstrapHostBuilder.Context, Configuration, Services);
    WebHost = new ConfigureWebHostBuilder(webHostContext, Configuration, Services);
  }

  其中ConfigureHostBuilder 对象 Host 就是用来配置autofac 容器的主要对象;

四 、autofac 容器使用

  autofac 在unget 中搜Autofac.Extensions.Dependen 并安装;

  使用方法如下:

  builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

  其中AutofacServiceProviderFactory 定义如下;

  public class AutofacServiceProviderFactory : IServiceProviderFactory<ContainerBuilder>{}

  源码如下:

  public IHostBuilder UseServiceProviderFactory<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory) where TContainerBuilder :   notnull
  {
    if (factory is null)
    {
      throw new ArgumentNullException(nameof(factory));
    }

    _serviceProviderFactory = new ServiceProviderFactoryAdapter<TContainerBuilder>(factory);
    return this;
  }

  定义的适配类源码如下:

private sealed class ServiceProviderFactoryAdapter<TContainerBuilder> : IServiceProviderFactory<object> where TContainerBuilder : notnull
{
private readonly IServiceProviderFactory<TContainerBuilder> _serviceProviderFactory;

public ServiceProviderFactoryAdapter(IServiceProviderFactory<TContainerBuilder> serviceProviderFactory)
{
_serviceProviderFactory = serviceProviderFactory;
}

public object CreateBuilder(IServiceCollection services) => _serviceProviderFactory.CreateBuilder(services);
public IServiceProvider CreateServiceProvider(object containerBuilder) => _serviceProviderFactory.CreateServiceProvider((TContainerBuilder)containerBuilder);
}

在调用 WebApplication  Builder() 过程 

  public WebApplication Build()
  {
    // ConfigureContainer callbacks run after ConfigureServices callbacks including the one that adds GenericWebHostService by default.
    // One nice side effect is this gives a way to configure an IHostedService that starts after the server and stops beforehand.
    _hostApplicationBuilder.Services.Add(_genericWebHostServiceDescriptor);
    Host.ApplyServiceProviderFactory(_hostApplicationBuilder);
    _builtApplication = new WebApplication(_hostApplicationBuilder.Build());
    return _builtApplication;
  }

接着 Host 对象调用ApplyServiceProviderFactor() 的过程如下:

  internal void ApplyServiceProviderFactory(HostApplicationBuilder hostApplicationBuilder)
  {
    if (_serviceProviderFactory is null)
    {
      // No custom factory. Avoid calling hostApplicationBuilder.ConfigureContainer() which might override default validation options.
      // If there were any callbacks supplied to ConfigureHostBuilder.ConfigureContainer(), call those with the IServiceCollection.
      foreach (var action in _configureContainerActions)
      {
        action(_context, _services);
      }

      return;
    }

    void ConfigureContainerBuilderAdapter(object containerBuilder)
    {
      foreach (var action in _configureContainerActions)
      {
        action(_context, containerBuilder);
      }
    }

    hostApplicationBuilder.ConfigureContainer(_serviceProviderFactory, ConfigureContainerBuilderAdapter);
  }

  其中 hostApplicationBuilder.ConfigureContainer()源码在 HostApplicationBuilder.cs

   https://github.com/dotnet/runtime/blob/e8b149109c8b04161b83d0e4c997b63759c6d936/src/libraries/Microsoft.Extensions.Hosting/src/

  如下图所示:

  

 

 记录一下,调用过程;

posted @ 2022-09-09 10:57  cdxy2005  阅读(548)  评论(0编辑  收藏  举报