代码改变世界

ASP.NET Core 下的依赖注入(一)

2019-04-25 18:57  音乐让我说  阅读(528)  评论(0编辑  收藏  举报

本文介绍利用 Microsoft.Extensions.Configuration.Binder.dll 来实现超级简单的注入。

 

1. appsettings.json 中定义配置

假设我们有如下配置:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Tecent": {
    "Qzone": {
      "Url": "http://i.qq.com",
      "CName": "QQ空间",
      "Age": 15
    },
    "Weixin": {

    }
  
  }
}

 

2. 定义配置模型类

    public interface ITecentConfig
    {
        QzoneConfig Qzone { get; set; }
    }

 

    public class TecentConfig : ITecentConfig
    {
        public QzoneConfig Qzone { get; set; }
    }

 

    public class QzoneConfig
    {
        public string Url { get; set; }

        public string CName { get; set; }

        public int Age { get; set; }
    }

 

 

 

3. Nuget 中引用 Microsoft.Extensions.Configuration.Binder.dll 

 

4.  编写 ServiceCollection 的扩展方法

    public static class ServiceCollectionExtensions
    {
        public static void ConfigureApplicationServices(this IServiceCollection services, IConfiguration configuration)
        {
            ITecentConfig tencentConfig = services.ConfigureStartupConfig<ITecentConfig, TecentConfig>(configuration.GetSection("Tecent"));

            //由于已经通过依赖注入了,并且单例模式,下面通过依赖注入读取配置。
            
        }

        public static TConfig ConfigureStartupConfig<TConfig>(this IServiceCollection services, IConfiguration configuration) 
            where TConfig : class, new()
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));
            if (configuration == null)
                throw new ArgumentNullException(nameof(configuration));
            var config = new TConfig();
            configuration.Bind(config);
            services.AddSingleton(config);
            //.NET Core DI 为我们提供的实例生命周其包括三种:
            //Transient: 每一次GetService都会创建一个新的实例
            //Scoped:  在同一个Scope内只初始化一个实例 ,可以
            //          理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内)
            //Singleton :整个应用程序生命周期以内只创建一个实例
            return config;
        }

        public static IConfig ConfigureStartupConfig<IConfig, ConfigImpl>(this IServiceCollection services, IConfiguration configuration)
            where ConfigImpl : class, IConfig, new()
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));
            if (configuration == null)
                throw new ArgumentNullException(nameof(configuration));
            var config = new ConfigImpl();
            configuration.Bind(config);
            services.AddSingleton(typeof(IConfig), config);
            return config;
        }
    }

 

这里需要解释一下,这里有 2 个重载方法  ConfigureStartupConfig, 第一个表示不用接口(或者抽象父类),直接读取配置成我们自己的配置模型,然后依赖注入单例。第二个方法表示只依赖接口或者抽象父类(指:我们自己定义的 ITencentConfig),不依赖具体的子类(指:我们自己定义的 TecentConfig)。

 

5. 在 Startup.cs 中注册服务

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

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
            });
            services.ConfigureApplicationServices(Configuration);//注册我们自定义的服务

            //注册自定义的模型绑定
            services.AddMvc()
            .AddNewtonsoftJson();
            services.AddRazorPages();
        }
}

 

6.  MVC 控制器中构造函数注入

    public class HomeController : Controller
    {
        private ITecentConfig _tecentConfig;

        public HomeController(ITecentConfig tecentConfig)
        {
            _tecentConfig = tecentConfig;
        }

        public IActionResult About()
        {
            return Content(string.Format("这个是 About 介绍。{0}: {1}。HashCode:{2}", 
                    _tecentConfig.Qzone.CName, 
                    _tecentConfig.Qzone.Url,
                    _tecentConfig.GetHashCode()
                    )
                );
        }
    }

 

7. 效果图

 

 

 

谢谢浏览!