前言
首先感謝小可愛門的支援,寫了這個系列的第二篇後,得到了好多人的鼓勵,也更加堅定我把這個系列寫完的決心,也能更好的督促自己的學習,分享自己的學習成果。還記得上篇文章中最後提及到,假如服務越來越多怎麼處理呢,本篇文章將會帶來解決辦法。這篇是接上一篇文章的,概念方面的可以參考上一篇文章。
IoC框架
先說說常見的Ioc框架吧。
Autofac: 目前net用的比較多,好多大佬的專案比較優先選擇的框架。
Ninject: 已經很少用了,還時在很早的文章中見過。
Unity: 比較常見的了,好多地方有用到的,
Core: Core中自帶的,業務邏輯不太複雜的情況下,還是比較方便的。
IoC-Autofac
Autofac是.NET領域最為流行的IOC框架之一,傳說是速度最快的一個。
優點:
- 它是C#語言聯絡很緊密,也就是說C#裡的很多程式設計方式都可以為Autofac使用。
- 較低的學習曲線,學習它非常的簡單,只要你理解了IoC和DI的概念以及在何時需要使用它們。
- XML.Json配置支援。
- 自動裝配。
- 與Asp.Net MVC 整合。
- 微軟的Orchad開源程式使用的就是Autofac,從該原始碼可以看出它的方便和強大。
大多數講Autofac框架的文章中都會提及上面幾點優點,可見其框架的優秀。
.NET Core中自帶DI的使用
1.首先建立一個 ASP.Net Core Web Api專案(選用的.NET 5.0),整體如下,紅色部分為Core中自帶DI使用的部分。
2.新建類庫專案,分別新增一個介面檔案和類檔案。
介面:
public interface ISayHelloService
{
string SayHello(string name);
}
類:
public class EnglishSayHelloService : ISayHelloService
{
public string SayHello(string name)
{
return $"Hello,{name}!";
}
}
3.在 Startup 裡面的 ConfigureServices 方法內注入。
services.AddScoped<ISayHelloService, EnglishSayHelloService>();
4.然後在控制器中使用剛剛注入的服務。
[Route("api/[controller]/[action]")]
[ApiController]
public class HelloController : ControllerBase
{
public readonly ISayHelloService sayHelloService;
public HelloController(ISayHelloService sayHelloService)
{
this.sayHelloService = sayHelloService;
}
[HttpGet]
public string CoreDI()
{
return sayHelloService.SayHello("CoreDI");
}
}
注意: 路由訪問地址,出現404錯誤時,可能是路由問題,路由可根據自己的實際需要自己在 [Route("api/[controller]/[action]")]
處修改。
5.訪問測試。
這裡使用的介面測試軟體是Postman,Api測試很方便,網上可以搜尋到,找不到我到的可以聯絡我。
Autofac 使用
1.在新建一個ASP.Net Core Web Api專案(選用的.NET 5.0)用於區分前面的Core自帶的DI。
2.引用引用 Autofac 的包,看看這下載量,還是很哇塞的
3.在 Program 中改用 Autofac 來實現依賴注入
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
4.在 Startup 類中新增方法:ConfigureContainer,注入我們之前的服務。
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
//在這裡注入
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType<EnglishSayHelloService>().As<ISayHelloService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
5.控制器這裡基本不需要更改。
[Route("api/[controller]/[action]")]
[ApiController]
public class HelloController : ControllerBase
{
public readonly ISayHelloService sayHelloService;
public HelloController(ISayHelloService sayHelloService)
{
this.sayHelloService = sayHelloService;
}
[HttpGet]
public string CoreDI()
{
return sayHelloService.SayHello("AutofacDI");
}
}
6.執行專案繼續用Postman測試介面。
好了關於Autofac的基本使用基本就講完了,是不是還是挺簡單的。
批量注入
簡單的幾個服務寫著還可以接受,當服務到幾十個,甚至上百個時,想想就可怕。這就不得不說到批量注入了,Autofac的優勢就體現出來了。
1.在服務中分別在新增一個介面,和類。
介面:
public interface IUseAutofacService
{
string UseAutofac(string name);
}
類:
public class UseAutofacService : IUseAutofacService
{
public string UseAutofac(string name)
{
return $"{name}批量注入測試!";
}
}
2.回到我們之前的Startup 類中修改方法:ConfigureContainer。
public void ConfigureContainer(ContainerBuilder builder)
{
//builder.RegisterType<EnglishSayHelloService>().As<ISayHelloService>();
//服務專案程式集
Assembly service = Assembly.Load("Autofac.Service");
//服務介面專案程式集
Assembly iservice = Assembly.Load("Autofac.Service");
builder.RegisterAssemblyTypes(service, iservice).Where(n => n.FullName.EndsWith("Service") && !n.IsAbstract)
.InstancePerLifetimeScope().AsImplementedInterfaces();
}
注意: 如果需要注入的服務沒有 IXXXService的介面 ,那麼 builder.RegisterAssemblyTypes 就只需要傳一個程式集。如果服務與介面同在一個專案,那也是要傳兩個程式集的。
3.接下來在剛剛的控制器中略作修改。
[Route("api/[controller]/[action]")]
[ApiController]
public class HelloController : ControllerBase
{
public readonly ISayHelloService sayHelloService;
public readonly IUseAutofacService useAutofacService;
public HelloController(ISayHelloService _sayHelloService, IUseAutofacService _useAutofacService)
{
this.sayHelloService = _sayHelloService;
this.useAutofacService = _useAutofacService;
}
[HttpGet]
public string AutofacDI()
{
return sayHelloService.SayHello("AutofacDI");
}
public string BathAutofacDI()
{
var name = sayHelloService.SayHello("AutofacDI");
return useAutofacService.UseAutofac(name);
}
}
4.用Postman測試注入的情況。