• .Net Core 依赖注入


    基本使用

    DI[1] 就不多说了,相信大家多多少少都有所了解。
    我们直接上代码,首先新建一个控制台应用程序。
    定义示例所使用的接口

    public interface IAnimal
    {
        void Say();
    }
    

    实现此接口

    public class Cat : IAnimal
    {
        public void Say()
        {
            Console.WriteLine("喵~");
        }
    }
    
    public class Dog : IAnimal
    {
        public void Say()
        {
            Console.WriteLine("汪~");
        }
    }
    

    NuGet Microsoft.Extensions.DependencyInjection

    PM> Install-Package Microsoft.Extensions.DependencyInjection

    这是在 .Net Core 中微软默认已经实现的DI[1:1]容器,并且使用广泛。

    示例

    IServiceCollection services = new ServiceCollection();
    services.AddTransient<IAnimal, Dog>();
    IServiceProvider provider = services.BuildServiceProvider();
    var animal = provider.GetService<IAnimal>();
    animal.Say();
    

    Note

    IServiceCollection 是一个重要的容器对象,用来确定注入关系。
    IServiceProvider 也是一个重要的对象,用来获取实例。

    生命周期

    • Transient 瞬时 生命周期服务在它们每次请求时被创建。这一生命周期适合轻量级的无状态服务。
    • Scoped 作用域 生命周期服务在每次请求时被创建一次。
    • Singleton 单例 生命周期服务在它们第一次被请求时创建(或者你使用了直接创建的重载函数),并且每个后续请求将使用相同的实例,如果你的应用程序需要单例行为,则建议让服务容器管理服务的生命周期,而不是在自己的类中实现单例模式和管理对象的生命周期。

    配置文件

    在 .Net Core 中的配置文件一般为 appsettings.json 或者 appsettings.环境变量.json,现在我们可以将配置文件中某一个节点映射成一个模型类的实例。

    配置节点

    {
      "Cryptography": {
        "DesKey": "1dD%8Il4",
        "TripleDesKey": "OTNbgW4#qVAl7wMqdbBN$Pjd",
        "AesKey": "GaHleK8&qHXFG0p4vb3QB&xbUovs7&7n"
      }
    }
    
    

    模型类

    
    public sealed class CryptographyOptions
    {
        public string DesKey { get; set; }
    
        public string TripleDesKey { get; set; }
    
        public string AesKey { get; set; }
    }
    
    

    NuGet Microsoft.Extensions.Options

    PM> Install-Package Microsoft.Extensions.Options

    首先使用扩展函数注册所需的服务

    services.AddOptions();
    

    注册配置节点和模型类的注入关系

    services.Configure<CryptographyOptions>(configuration.GetSection("Cryptography"));
    

    Note

    configurationIConfiguration 的实例

    示例

    public sealed class Cryptography
    {
        public readonly CryptographyOptions Options;
    
        public Cryptography(IOptions<CryptographyOptions> configOption)
        {
            Options = configOption.Value;
        }
    }
    

    EntityFramework

    NuGet Microsoft.EntityFrameworkCore

    PM> Install-Package Microsoft.EntityFrameworkCore

    可以通过 services.AddDbContextservices.AddDbContextPool 扩展函数来添加 EntityFramework 的 DbContext 对象的注入。

    MVC

    NuGet Microsoft.AspNetCore.Mvc

    PM> Install-Package Microsoft.AspNetCore.Mvc

    可以通过 services.AddMvc 扩展函数来添加MVC的对象注入关系。

    使用 autofac 替换注入容器

    Microsoft.Extensions.Options 所提供的注入容器中,目前我只发现了构造函数注入这种方式,但是接触过 DI[1:2] 的朋友都知道现在的注入容器多多少少都会提供一些更加高级的功能,比如 属性注入、条件注入、模块注入……等,所以我们在这里使用 autofac 来替换注入容器,实现这些高级功能。当然注入容器不止 autofac ,还有 Ninject、著名的 castleproject 中的 Windsor (Abp.Net 中就是使用的这个) 等等。

    NuGet Autofac.Extensions.DependencyInjection

    PM> Install-Package Autofac.Extensions.DependencyInjection

    示例

    在 .Net Core Mvc Application 中 Startup 类中的 ConfigureServices 函数,将 void 返回类型修改为 IServiceProvider

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        var builder = new ContainerBuilder();
        //注入关系
    
        builder.Populate(services);
        return new AutofacServiceProvider(builder.Build());
    }
    

    Note

    由于 MVC 中 Controller 的实例创建是由自己控制的,要实现高级注入功能,必须要让 Controller 的创建过程由注入容器来控制,所以修改代码为:

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
        services.AddMvc().AddControllersAsServices();
        var builder = new ContainerBuilder();
        //注入关系
    
        builder.Populate(services);
        return new AutofacServiceProvider(builder.Build());
    }
    

    参考资料


    1. 依赖注入(Dependency Injection) ↩︎ ↩︎ ↩︎

  • 相关阅读:
    Best Practices for Background Jobs_3 Managing Device Awake State之电源锁、Alarm、WakefulBroadcastReceiver
    一种扩大View点击范围的方法
    IntentService
    DNS
    GPU硬件加速相关
    SOA 面向服务的体系结构
    android APK 文件的生成过程
    PHP简介
    代码安装apk文件
    View 的 focus 和 selected 状态, TabContainer实现
  • 原文地址:https://www.cnblogs.com/OrangeTree/p/9207655.html
Copyright © 2020-2023  润新知