ASP .Net Core依赖注入

文章介绍了ASP.NETCore中依赖注入的概念,包括Transient、Scoped和Singleton三种服务生命周期,并通过示例展示了如何注入自定义服务,如InfluxDb查询服务。此外,还讨论了如何通过封装扩展服务来简化Startup类的配置,提高代码可维护性。
摘要由CSDN通过智能技术生成

在新的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,接口里面我只写了两个接口。

publicinterfaceIInfluxDbService
{
    voidAddData(string tableName,
        Dictionary<string, object> tags,
        Dictionary<string, object> fields, DateTime timestamp);

    IList<IList<object>> GetData(string queries);
}
  1. 编写服务,继承自接口,InfluxDbService.cs
    可以看到带了一个含参构造函数,传入数据库地址及用户密码等必须信息。

publicclassInfluxDbService:IInfluxDbService
    {
        //声明InfluxDbClientprivate InfluxDbClient clientDb;
        privatestring dbName;

        publicInfluxDbService(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>publicasyncvoidAddData(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作为示例进行演示。

publicvoidConfigureServices(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>publicstaticclassServiceExtensions
    {
        ///<summary>/// 添加跨域///</summary>///<param name="services"></param>publicstaticvoidConfigureCors(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>publicstaticvoidAddInfluxDbService(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;
    publicCurrentStatusController(IInfluxDbService influxDbService){
        _influxDbService = influxDbService;
    }

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值