控制反轉(Inversion of Control,IoC),是面向對象編程中的一種設計原則,用來下降代碼之間的耦合度。編程
依賴原則:api
(1)高層次的模塊不該該依賴於低層次的模塊,它們都應該依賴於抽象。ide
(2)抽象不該該依賴於具體,具體應該依賴於抽象。ui
依賴注入:把依賴部分(代碼不可控或者常常變更的耦合的部分)變成一個抽象的成員(類、抽象類或接口),而後根據具體所須要的實例去靈活的注入依賴,來達到控制反轉的效果,從而實現代碼解耦。spa
依賴注入是控制反轉的一種具體實現方式。設計
C#經常使用的依賴注入方式:code
(1)經過構造器進行依賴注入對象
(2)經過屬性的訪問器進行依賴注入blog
(3)經過接口實現依賴注入接口
(4)經過反射,特性也能夠實現依賴注入
依賴注入安裝包:
Install-Package Microsoft.Extensions.DependencyInjection
ASP.NET Core 提供了一個內置的服務容器 IServiceProvider,在 Startup.ConfigureServices 方法中配置依賴注入。
ASP.NET Core 註冊服務生存期:
(1)AddTransient:暫時生存期,每次從服務容器進行請求時建立。
(2)AddScoped:做用域生存期,每一個客戶端請求(鏈接)一次建立。
(3)AddSingleton:單一實例生存期服務,在第一次請求時建立,每一個後續請求都使用相同的實例。
示例:
public interface ILogRepository { int Insert(Log log); }
public class LogRepository : ILogRepository { public int Insert(Log log) { using (var context = new PortalContext()) { context.Logs.Add(new Log { UserName = log.UserName, Content = log.Content, CreateTime = DateTime.Now }); return context.SaveChanges(); } } }
Startup.cs
using Microsoft.Extensions.DependencyInjection; public void ConfigureServices(IServiceCollection services) { services.AddScoped<ILogRepository, LogRepository>(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
LogController.cs
[Route("api/[controller]")] [ApiController] public class LogController : ControllerBase { private readonly ILogRepository _logRepository; public LogController(ILogRepository logRepository) { _logRepository = logRepository; } [HttpPost] public void Post([FromBody] Log value) { _logRepository.Insert(value); } }
添加安裝包:
Install-Package Autofac.Extensions.DependencyInjection
Startup.cs:
using Autofac; using Autofac.Extensions.DependencyInjection; // 使用第三方容器,Startup.ConfigureServices 必須返回 IServiceProvider public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); // Autofac var builder = new ContainerBuilder(); builder.RegisterType<LogRepository>().As<ILogRepository>(); builder.Populate(services); var container = builder.Build(); return new AutofacServiceProvider(container); }