zoukankan      html  css  js  c++  java
  • asp.net Core依赖注入(自带的IOC容器)

    今天我们主要讲讲如何使用自带IOC容器,虽然自带的功能不是那么强大,但是胜在轻量级..而且..不用引用别的库.

    在新的ASP.NET Core中,大量的采用了依赖注入的方式来编写代码.

    比如,在我们的Startup类中的ConfigureServices里,就可以看到:

    AddMvc AddDbContext 包括我们之前目录游览用到的AddDirectoryBrowser..

    都是框架提供好的服务,我们直接注入就可以使用了.

    如何注入自己的服务

    目前有三种注入,各有不同:

    • Transient(瞬时的)
      每次请求时都会创建的瞬时生命周期服务。这个生命周期最适合轻量级,无状态的服务。
    • Scoped(作用域的)
      创建的对象在同一个请求会话时是相同的,每一个不同的会话创建一个不同的实例。
    • Singleton(唯一的)
      创建的对象在所有的地方所有的请求会话创建的都是不同的。

    如何使用这三种生命周期呢?.我们直接在注入的时候用不同的方法就行了,代码如下:

    services.AddTransient<ITestService, TestService>();
    services.AddScoped<ITestService, TestService>();
    services.AddSingleton<ITestService, TestService>();
    

    编写服务

    我这里写了一个查询InfluxDb的服务,就用这个作为例子来分析。

    1. 首先定义接口,IInfluxDbService.cs,接口里面我只写了两个接口。
    public interface IInfluxDbService
    {
        void AddData(string tableName,
            Dictionary<string, object> tags,
            Dictionary<string, object> fields, DateTime timestamp);
    
        IList<IList<object>> GetData(string queries);
    }
    
    1. 编写服务,继承自接口,InfluxDbService.cs
      可以看到带了一个含参构造函数,传入数据库地址及用户密码等必须信息。
        public class InfluxDbService:IInfluxDbService
        {
            //声明InfluxDbClient
            private InfluxDbClient clientDb;
            private string dbName;
    
            public InfluxDbService(string infuxUrl, string dbName,string infuxUser, string infuxPwd)
            {
                this.dbName = dbName;
                clientDb = new InfluxDbClient(infuxUrl, infuxUser, infuxPwd, InfluxDbVersion.Latest);
            }
            /// <summary>
            /// 增加数据
            /// </summary>
            /// <param name="tableName">表名</param>
            /// <param name="tags">索引</param>
            /// <param name="fields">字段</param>
            /// <param name="timestamp">时间戳</param>
            public async void AddData(string tableName,
                Dictionary<string,object> tags,
                Dictionary<string,object> fields,DateTime timestamp)
            {
                //基于InfluxData.Net.InfluxDb.Models.Point实体准备数据
                var pointModel = new Point();
                pointModel.Name = tableName;
                pointModel.Tags = tags;
                pointModel.Fields = fields;
                pointModel.Timestamp = timestamp;
               
                //从指定库中写入数据,支持传入多个对象的集合
                var response = await clientDb.Client.WriteAsync(pointModel, this.dbName);
            }
    
            /// <summary>
            /// 查询数据
            /// </summary>
            /// <param name="queries"></param>
            /// <returns>返回查询结果</returns>
            public IList<IList<object>> GetData(string queries)
            {
                //从指定库中查询数据
                var response =  clientDb.Client.QueryAsync(queries, this.dbName);
                //得到Serie集合对象(返回执行多个查询的结果)
                var series = response.Result.ToList();
                var list = series[0].Values;
                return list;
            }
        }
    

    这样我们的服务就写完了,接下来就是如何注入服务。

    依赖注入

    我们可以在Startup类中直接注入,比如,我这里就拿AddSingleton作为示例进行演示。

    public void ConfigureServices(IServiceCollection services)
    {
        //读配置文件获取参数
        var url = configuration.GetValue("InfluxDb:ConnectionString", "http://127.0.0.1:8086");
        var dbName = configuration.GetValue("InfluxDb:DatabaseName", "autocontrol");
        var userName = configuration.GetValue("InfluxDb:UserName", "admin");
        var password = configuration.GetValue("InfluxDb:Password", "admin");
        //注入依赖
        services.AddSingleton<IInfluxDbService, InfluxDbService>(a => new InfluxDbService(url, dbName, userName, password));
        //以下是系统自动生成
        services.AddControllersWithViews();
        services.AddMvcCore().AddApiExplorer();
    }
    

    只因我这里加入了很多参数,代码就有一大坨了,如果所有服务都这样写,可以想象下,如果服务很多,那么这个方法就会越来越长,后期很难维护,代码看起来也不优雅美观,为了减少ConfigureServices这个函数体的长度,我们可以把这一段封装起来。

    封装扩展服务

    1. 首先新建一个ServiceExtensions的静态类
        /// <summary>
        /// 服务扩展类
        /// </summary>
        public static class ServiceExtensions
        {
            /// <summary>
            /// 添加跨域
            /// </summary>
            /// <param name="services"></param>
            public static void ConfigureCors(this IServiceCollection services)
            {
                services.AddCors(options =>
                {
                    options.AddPolicy("AllowAny", builder => builder.SetIsOriginAllowed(isOriginAllowed: _ => true)
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials());
                });
            }
    
            /// <summary>
            /// 注入InfluxDb服务
            /// </summary>
            /// <param name="services"></param>
            /// <param name="configuration"></param>
            public static void AddInfluxDbService(this IServiceCollection services, IConfiguration configuration)
            {
                //服务DI注入
                var url = configuration.GetValue("InfluxDb:ConnectionString", "http://127.0.0.1:8086");
                var dbName = configuration.GetValue("InfluxDb:DatabaseName", "autocontrol");
                var userName = configuration.GetValue("InfluxDb:UserName", "admin");
                var password = configuration.GetValue("InfluxDb:Password", "admin");
    
                services.AddSingleton<IInfluxDbService, InfluxDbService>(a => new InfluxDbService(url, dbName, userName, password));
    
            }
        }
    

    我这里封装了两个服务。

    • ConfigureCors:跨域的服务
    • AddInfluxDbService:InfluxDb的服务
    public void ConfigureServices(IServiceCollection services)
    {
        //设置跨域处理
        services.ConfigureCors();
        //注入服务
        services.AddInfluxDbService(Configuration);
    
        services.AddControllersWithViews();
                
        services.AddMvcCore().AddApiExplorer();
    }
    

    这样就相当简洁了,哈哈

    控制器

    修改控制器代码如下

        private IInfluxDbService _influxDbService;
        public CurrentStatusController(IInfluxDbService influxDbService)
        {
            _influxDbService = influxDbService;
        }
    

    这样就控制器就可以使用_influxDbService来操作数据库了

  • 相关阅读:
    Mysql上手
    Markdown精简版个人语法
    Sublime Text3插件管理
    Eclipse的快捷键
    使用github page 页面建博客中遇到的几个小问题
    2015 圣诞 限免软件分享
    啦啦啦-根据关键字进行字符串拷贝
    使用 sprintf swprintf 函数进行 unicode 与 ANSI 编码的转换
    c++11: 用户定义字面量
    通过模板获取数组长度
  • 原文地址:https://www.cnblogs.com/zhanwei103/p/12728877.html
Copyright © 2011-2022 走看看