今天我們主要講講如何使用自帶IOC容器,雖然自帶的功能不是那么強(qiáng)大,但是勝在輕量級(jí)..而且..不用引用別的庫(kù).
在新的ASP.NET Core中,大量的采用了依賴(lài)注入的方式來(lái)編寫(xiě)代碼.
比如,在我們的Startup類(lèi)中的ConfigureServices里,就可以看到:
AddMvc AddDbContext 包括我們之前目錄游覽用到的AddDirectoryBrowser..
都是框架提供好的服務(wù),我們直接注入就可以使用了.
如何注入自己的服務(wù)
目前有三種注入,各有不同:
- Transient(瞬時(shí)的)
每次請(qǐng)求時(shí)都會(huì)創(chuàng)建的瞬時(shí)生命周期服務(wù)。這個(gè)生命周期最適合輕量級(jí)沦疾,無(wú)狀態(tài)的服務(wù)垮耳。 - Scoped(作用域的)
創(chuàng)建的對(duì)象在同一個(gè)請(qǐng)求會(huì)話(huà)時(shí)是相同的跃须,每一個(gè)不同的會(huì)話(huà)創(chuàng)建一個(gè)不同的實(shí)例眷篇。 - Singleton(唯一的)
創(chuàng)建的對(duì)象在所有的地方所有的請(qǐng)求會(huì)話(huà)創(chuàng)建的都是不同的舆瘪。
如何使用這三種生命周期呢?.我們直接在注入的時(shí)候用不同的方法就行了,代碼如下:
services.AddTransient<ITestService, TestService>();
services.AddScoped<ITestService, TestService>();
services.AddSingleton<ITestService, TestService>();
編寫(xiě)服務(wù)
我這里寫(xiě)了一個(gè)查詢(xún)InfluxDb的服務(wù)池摧,就用這個(gè)作為例子來(lái)分析焦除。
- 首先定義接口,IInfluxDbService.cs,接口里面我只寫(xiě)了兩個(gè)接口作彤。
public interface IInfluxDbService
{
void AddData(string tableName,
Dictionary<string, object> tags,
Dictionary<string, object> fields, DateTime timestamp);
IList<IList<object>> GetData(string queries);
}
- 編寫(xiě)服務(wù),繼承自接口膘魄,InfluxDbService.cs
可以看到帶了一個(gè)含參構(gòu)造函數(shù)乌逐,傳入數(shù)據(jù)庫(kù)地址及用戶(hù)密碼等必須信息。
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>
/// 增加數(shù)據(jù)
/// </summary>
/// <param name="tableName">表名</param>
/// <param name="tags">索引</param>
/// <param name="fields">字段</param>
/// <param name="timestamp">時(shí)間戳</param>
public async void AddData(string tableName,
Dictionary<string,object> tags,
Dictionary<string,object> fields,DateTime timestamp)
{
//基于InfluxData.Net.InfluxDb.Models.Point實(shí)體準(zhǔn)備數(shù)據(jù)
var pointModel = new Point();
pointModel.Name = tableName;
pointModel.Tags = tags;
pointModel.Fields = fields;
pointModel.Timestamp = timestamp;
//從指定庫(kù)中寫(xiě)入數(shù)據(jù)创葡,支持傳入多個(gè)對(duì)象的集合
var response = await clientDb.Client.WriteAsync(pointModel, this.dbName);
}
/// <summary>
/// 查詢(xún)數(shù)據(jù)
/// </summary>
/// <param name="queries"></param>
/// <returns>返回查詢(xún)結(jié)果</returns>
public IList<IList<object>> GetData(string queries)
{
//從指定庫(kù)中查詢(xún)數(shù)據(jù)
var response = clientDb.Client.QueryAsync(queries, this.dbName);
//得到Serie集合對(duì)象(返回執(zhí)行多個(gè)查詢(xún)的結(jié)果)
var series = response.Result.ToList();
var list = series[0].Values;
return list;
}
}
這樣我們的服務(wù)就寫(xiě)完了浙踢,接下來(lái)就是如何注入服務(wù)。
依賴(lài)注入
我們可以在Startup類(lèi)中直接注入,比如灿渴,我這里就拿AddSingleton作為示例進(jìn)行演示洛波。
public void ConfigureServices(IServiceCollection services)
{
//讀配置文件獲取參數(shù)
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");
//注入依賴(lài)
services.AddSingleton<IInfluxDbService, InfluxDbService>(a => new InfluxDbService(url, dbName, userName, password));
//以下是系統(tǒng)自動(dòng)生成
services.AddControllersWithViews();
services.AddMvcCore().AddApiExplorer();
}
只因我這里加入了很多參數(shù),代碼就有一大坨了骚露,如果所有服務(wù)都這樣寫(xiě)蹬挤,可以想象下,如果服務(wù)很多棘幸,那么這個(gè)方法就會(huì)越來(lái)越長(zhǎng)焰扳,后期很難維護(hù),代碼看起來(lái)也不優(yōu)雅美觀(guān)误续,為了減少ConfigureServices這個(gè)函數(shù)體的長(zhǎng)度吨悍,我們可以把這一段封裝起來(lái)。
封裝擴(kuò)展服務(wù)
- 首先新建一個(gè)ServiceExtensions的靜態(tài)類(lèi)
/// <summary>
/// 服務(wù)擴(kuò)展類(lèi)
/// </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服務(wù)
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddInfluxDbService(this IServiceCollection services, IConfiguration configuration)
{
//服務(wù)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));
}
}
我這里封裝了兩個(gè)服務(wù)女嘲。
- ConfigureCors:跨域的服務(wù)
- AddInfluxDbService:InfluxDb的服務(wù)
public void ConfigureServices(IServiceCollection services)
{
//設(shè)置跨域處理
services.ConfigureCors();
//注入服務(wù)
services.AddInfluxDbService(Configuration);
services.AddControllersWithViews();
services.AddMvcCore().AddApiExplorer();
}
這樣就相當(dāng)簡(jiǎn)潔了畜份,哈哈
控制器
修改控制器代碼如下
private IInfluxDbService _influxDbService;
public CurrentStatusController(IInfluxDbService influxDbService)
{
_influxDbService = influxDbService;
}
這樣就控制器就可以使用_influxDbService來(lái)操作數(shù)據(jù)庫(kù)了