目錄
- 前言
- Autofac
- 添加一個Util來隨時呼叫
- 小結
- 代碼地址
- 預告
前言
周末加班,下午犯困,整理下之前鼓搗過的東西,看過我之前的webapi系列的讀者知道,我之前試過Aspect,但是升級到3.0之后沒往下去試了,當時還留了個坑,這不,現在果斷移除了換成這個了,
Autofac
這個第三方類別庫呢,是Ioc的容器,可以簡化我們很大的作業量,比如說在之前我們需要寫個類去宣告介面與實作,而用了這個容器呢,就不需要了,當然還是需要些配置的,
首先,引入第三方類別庫,不多說,

然后開始配置吧,首先先來看Program,添加AutofacServiceProviderFactory,
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
改完之后呢,我們果斷就來到了Startup,只要是配置,當然要看入口檔案跟這個組態檔了,
3.x呢有個變化就是Autofac要通過ConfigureContainer這個傳入容器的方法來配置了,不需要自己再創建,
private static readonly List<string> _Assemblies = new List<string>()
{
"April.Service"
};
public void ConfigureContainer(ContainerBuilder container)
{
var assemblys = _Assemblies.Select(x => Assembly.Load(x)).ToList();
List<Type> allTypes = new List<Type>();
assemblys.ForEach(aAssembly =>
{
allTypes.AddRange(aAssembly.GetTypes());
});
// 通過Autofac自動完成依賴注入
container.RegisterTypes(allTypes.ToArray())
.AsImplementedInterfaces()
.PropertiesAutowired()
.InstancePerDependency();
// 注冊Controller
container.RegisterAssemblyTypes(typeof(Startup).GetTypeInfo().Assembly)
.Where(t => typeof(Controller).IsAssignableFrom(t) && t.Name.EndsWith("Controller", StringComparison.Ordinal))
.PropertiesAutowired();
}
通過RegisterTypes的注冊方法將對應工程,也就是April.Service下的類介面與實作自動系結,當然你也可以通過注冊介面的方法一個個來,但是我懶,比如:
// 一個
builder.RegisterType<StudentService>().As<IStudentService>();
// 一對多
builder.RegisterType<StudentService>().As<IStudentService>().As<ITestService>();
這里注意,宣告系結一般是一對一,當然也可以是一對多,如果多次注冊宣告一個類,會取最后一次注冊的宣告作為實際操作的類,
好了,配置完成之后,我們來試下效果吧(當然我是已經注釋掉之前的ServiceInjection這個宣告方法了),
在我們訪問Values的時候,我們看下IStudentService是否是null,

OK,這已經說明通過Autofac這個容器,已經完成了一個工程里面的介面與實作的依賴關系了,
添加一個Util來隨時呼叫
在接觸的朋友中,有人給我反饋個資訊,我不想每次寫方法都要建構式來傳介面方法給我,也就是說我不要你覺得,我要我覺得,
好啊,你覺得方法自己要啥拿啥,可以,來個Util吧,
public class AutofacUtil
{
public static ILifetimeScope Container { get; set; }
/// <summary>
/// 獲取服務(Single)
/// </summary>
/// <typeparam name="T">介面型別</typeparam>
/// <returns></returns>
public static T GetService<T>() where T : class
{
return Container.Resolve<T>();
}
/// <summary>
/// 獲取服務(請求生命周期內)
/// </summary>
/// <typeparam name="T">介面型別</typeparam>
/// <returns></returns>
public static T GetScopeService<T>() where T : class
{
return (T)GetService<IHttpContextAccessor>().HttpContext.RequestServices.GetService(typeof(T));
}
}
在用之前,我們需要針對Container來個宣告實體化,Startup中的Configure添加下面一句,
AutofacUtil.Container = app.ApplicationServices.GetAutofacRoot();
修改Values中的一部分來通過實體化的方式來呼叫介面,
IStudentService studentService = AutofacUtil.GetScopeService<IStudentService>();
StudentEntity entity = new StudentEntity
{
//新增
Name = "小明",
Age = 18,
Number = "007",
Sex = 0,
Address = "大洛陽"
};
studentService.Insert(entity);
讓我們來看下效果吧,

兩種方法,看個人習慣吧,我是推薦通過注入的方式,通過建構式的方式來獲取介面實作,
小結
簡單記錄平時鼓搗的點點滴滴,有時候真是覺得,還是要多看多鼓搗,就像這個容器,在之前我通過一行一行的介面+實作來做系結宣告,現在呢,只需要改造下,就可以一鍵無腦實體化,第三方庫的使用與否,個人覺得還是能踩著巨人的肩膀哪怕靠著也可以,自己一步步爬固然可嘉,也要學會變通,這樣方能提高效率,路漫漫其修遠兮,
代碼地址
注意切換到3.0的分支,
github
gitee
預告
April-Admin,總算是要有個前后端聯動的工程了,一個名副其實的基礎工程,
前端基于Ant Design Pro
后端當然是net core 3.1了

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/143947.html
標籤:其他
