目录
一:什么是IOC容器
IOC容器是Inversion Of Control的缩写,翻译的意思就是控制反转。
DI依赖注入是Dependency Injection的缩写,翻译的意思就是依赖注入。
通过抽象【接口、抽象类、普通父类】获取具体的实例。
Ioc容器是创建对象并给对象中的属性赋值交由工厂管理,达到控制反转的目的。再通过DI依赖注入让工厂来管理对象的创建和属性的赋值。
Ioc容器的优点:实现组件之间的解耦,提高程序的灵活性、扩展性和可维护性。
内置Ioc容器目前只支持构造函数注入,属性注入和方法注入请使用Autofac或其他第三方容器。
二:简单理解内置Ioc容器
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Study_ASP.NET_Core_MVC.ConsoleApp
{
public static class Program
{
public static void Main(string[] args)
{
//内置容器
//1:Nuget引入Microsoft.Extensions.DependencyInjection.Abstractions
//2:创建容器并初始化
ServiceCollection serviceCollection = new ServiceCollection();
//3:注册抽象和具体和普通类之间的关系
serviceCollection.AddTransient<IPhone, ApplePhone>();
//4:serviceCollection.Build一下
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
//5:获取对象的实例
IPhone iPhone = serviceProvider.GetService<IPhone>();
//6:内置容器调用方法
iPhone.Call();
iPhone.Text();
Console.ReadLine();
}
}
/// <summary>
/// Interfaces层
/// </summary>
public interface IPhone
{
/// <summary>
/// 打电话方法
/// </summary>
void Call();
/// <summary>
/// 发短信方法
/// </summary>
void Text();
}
/// <summary>
/// Services层
/// </summary>
public class ApplePhone : IPhone
{
private IPhone? iPhone;
public ApplePhone(IPhone? iPhone)
{
this.iPhone = iPhone;
}
/// <summary>
/// 打电话方法
/// </summary>
public void Call()
{
Console.WriteLine("{0}打电话", this.GetType().Name);
}
/// <summary>
/// 发短信方法
/// </summary>
public void Text()
{
Console.WriteLine("{0}发短信", this.GetType().Name);
}
}
}
三:构造函数依赖注入内置Ioc容器
MicroPhone没有依赖。
HeadPhone依赖MicroPhone。
ApplePhone依赖HeadPhone。
IPhone关键代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study_ASP.NET_Core_MVC.Interfaces
{
public interface IPhone
{
IMicroPhone MicroPhone { get; set; }
IHeadPhone HeadPhone { get; set; }
/// <summary>
/// 打电话方法
/// </summary>
void Call();
/// <summary>
/// 发短信方法
/// </summary>
void Text();
/// <summary>
/// 显示当前时间信息
/// </summary>
/// <param name="msgInfo">时间信息</param>
/// <returns></returns>
string ShowTime(string timeInfo);
}
public interface IMicroPhone { }
public interface IHeadPhone { }
}
ApplePhone关键代码:
using Study_ASP.NET_Core_MVC.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study_ASP.Net_Core_MVC.Services
{
public class ApplePhone : IPhone
{
public IMicroPhone MicroPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public IHeadPhone HeadPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public ApplePhone()
{
Console.WriteLine("{0}无参构造函数", this.GetType().Name);
}
public ApplePhone(IHeadPhone headPhone)
{
Console.WriteLine("{0}有参构造函数:{1}", this.GetType().Name,headPhone);
}
/// <summary>
/// 打电话方法
/// </summary>
public void Call()
{
Console.WriteLine("{0}打电话", this.GetType().Name);
}
/// <summary>
/// 发短信方法
/// </summary>
public void Text()
{
Console.WriteLine("{0}发短信", this.GetType().Name);
}
/// <summary>
/// 显示当前时间信息
/// </summary>
/// <param name="msgInfo">时间信息</param>
/// <returns></returns>
public string ShowTime(string timeInfo)
{
Console.WriteLine("显示时间:{0}", timeInfo);
return $"当前时间:{timeInfo}";
}
}
}
HeadPhone关键代码:
using Study_ASP.NET_Core_MVC.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study_ASP.Net_Core_MVC.Services
{
public class HeadPhone : IHeadPhone
{
private IMicroPhone microPhone;
public HeadPhone(IMicroPhone iMicroPhone)
{
Console.WriteLine($"{this.GetType().Name}被构造。。");
this.microPhone = iMicroPhone;
}
}
}
MicroPhone关键代码:
using Study_ASP.NET_Core_MVC.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study_ASP.Net_Core_MVC.Services
{
public class MicroPhone : IMicroPhone
{
public MicroPhone()
{
Console.WriteLine($"{this.GetType().Name}被构造。。。");
}
}
}
Program关键代码:
//表示整个应用程序,调用CreateBuilder方法创建一个WebApplicationBuilder对象。
//初始化当前应用程序的管道容器
using Microsoft.Extensions.DependencyInjection;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
var builder = WebApplication.CreateBuilder(args);
//向管道容器添加注册中间件
//添加注册控制器视图中间件
builder.Services.AddControllersWithViews();
//添加注册Session中间件
builder.Services.AddSession();
//注册Ioc容器服务
builder.Services.AddTransient<IMicroPhone, MicroPhone>();
builder.Services.AddTransient<IHeadPhone, HeadPhone>();
builder.Services.AddTransient<IPhone, ApplePhone>();
//配置管道容器中间件,构造WebApplication实例
var app = builder.Build();
//判断是否是开发模式
if (!app.Environment.IsDevelopment())
{
//向管道中添加中间件,该中间件将捕获异常、记录异常、重置请求路径并重新执行请求。
app.UseExceptionHandler("/Shared/Error");
//向管道中添加用于使用HSTS的中间件,该中间件添加了Strict Transport Security标头。默认值为30天
app.UseHsts();
}
//向管道添加Session中间件
app.UseSession();
//向管道添加用于将HTTP请求重定向到HTTPS的中间件。
app.UseHttpsRedirection();
//向管道添加为当前请求路径启用静态文件服务
app.UseStaticFiles();
//向管道添加路由配置中间件
app.UseRouting();
//向管道添加鉴权中间件
app.UseAuthentication();
//向管道添加授权中间件
app.UseAuthorization();
//向管道添加默认路由中间件
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
//向管道添加启动应用程序中间件
app.Run();
控制器关键代码:
using Microsoft.AspNetCore.Mvc;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;
using System.Diagnostics;
namespace Study_ASP.NET_Core_MVC.Controllers
{
public class HomeController : Controller
{
/// <summary>
/// 定义构造函数
/// </summary>
private readonly ILogger<HomeController> _logger;
private readonly IPhone iPhone;
private readonly IMicroPhone microPhone;
private readonly IHeadPhone headPhone;
/// <summary>
/// 初始化构造函数
/// </summary>
/// <param name="logger"></param>
public HomeController(ILogger<HomeController> logger, IPhone iPhone,IMicroPhone microPhone,IHeadPhone headPhone)
{
_logger = logger;
this.iPhone = iPhone;
this.microPhone = microPhone;
this.headPhone = headPhone;
}
/// <summary>
/// Get请求
/// Home控制器
/// Index方法
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Index()
{
//调用打电话方法
iPhone.Call();
//调用发短信方法
iPhone.Text();
//电泳显示实践方法
ViewBag.ShowTime = iPhone.ShowTime(DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"));
return View();
}
}
}
视图代码:
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<h1 class="display-4">@ViewBag.ShowTime</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
结果:
四:生命周期
瞬时生命周期:Transient:AddTransient:在整个应用程序中,每次请求都会创建一个全新的实例。生命周期最短。
单例生命周期:Singleton:AddSingleton:在整个应用程序中,创建一个实例,后续请求都会使用该实例。生命周期最长。
作用域生命周期:Scoped:AddScoped:在整个应用程序中,同一个域内,创建一个实例,后续请求都会使用该实例。
五:多种注册方式
public static void Main(string[] args)
{
//注册抽象和具体普通类
{
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<IPhone, ApplePhone>();
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
IPhone iPhone = serviceProvider.GetService<IPhone>();
//6:内置容器调用方法
iPhone.Call();
iPhone.Text();
}
//注册抽象和具体普通类
{
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddTransient(typeof(IPhone), typeof(ApplePhone));
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
IPhone iPhone = serviceProvider.GetService<IPhone>();
//6:内置容器调用方法
iPhone.Call();
iPhone.Text();
}
//注册具体抽象类
{
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddTransient(typeof(ApplePhone));
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
ApplePhone applePhone = serviceProvider.GetService<ApplePhone>();
//6:内置容器调用方法
applePhone.Call();
applePhone.Text();
}
//注册具体抽象类
{
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<ApplePhone>();
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
ApplePhone applePhone = serviceProvider.GetService<ApplePhone>();
//6:内置容器调用方法
applePhone.Call();
applePhone.Text();
}
//注册抽象类和一段业务逻辑
{
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddTransient(typeof(IPhone), provider =>
{
//业务逻辑
return provider;
});
serviceCollection.AddTransient(typeof(IPhone), typeof(ApplePhone));
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
IPhone iPhone = serviceProvider.GetService<IPhone>();
//6:内置容器调用方法
iPhone.Call();
iPhone.Text();
}
Console.ReadLine();
}