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来操作数据库了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容