※This article is based on .NET 7
控制反转是一种思想,依赖注入是一种设计模式,控制反转的思想可以利用依赖注入的设计模式实现,反射是依赖注入实现过程的核心技术。
Dependency Injection(DI)依赖关系注入是IoC的一种具体实现方式。在DI中,服务提供方和服务使用方之间的耦合关系由第三方组件(DI容器)来处理。容器负责实例化服务,并将其注入到需要该服务的类中。
ASP.NET Core中的DI容器可以帮助我们解决应用程序中的对象管理问题,例如创建对象、管理对象的生命周期等。
DI要做的两个功能是:
若要利用 .NET Core DI 框架,你只需引用 Microsoft.Extnesions.DependencyInjection.Abstractions NuGet 包。
如下应用程序代码获得了一个实例:
ILoggingFactory loggingFactor = serviceProvider.GetService<ILoggingFactory>();
注册后可以在整个Solution调用
Asp.Net Core 提供了默认的依赖注入(DI:Dependency Injection)容器 IServiceCollection,它是一个轻量级的依赖注入容器
在ASP.NET Core中,我们使用ServiceCollection容器来注册服务。ServiceCollection类继承于IServiceCollection接口,用于注册服务描述符并最终构建出ServiceProvider容器。ServiceCollection提供了一系列方便的方法来简化服务注册的过程。例如,通过调用AddTransient、AddScoped、AddSingleton等方法,我们可以轻松地注册服务。
ServiceCollection会在构建出ServiceProvider容器之前验证注册的服务描述符,以确保其合法性。例如,当注册多个同一服务类型的描述符时,ServiceCollection会抛出异常。另外,在 ServiceCollection.BuildServiceProvider() 方法中,容器将递归检查和解析所有服务描述符,构造出DI框架的核心实例(ServiceProvider)。
IServiceCollection依赖注入生命周期和其他大多数依赖注入容器一样,分为
我们可以在Startup.cs文件中的ConfigureServices方法中直接使用它。
这里我们单独把它拿出来看一下具体怎么使用,我们定义ITestService1,ITestService2,ITestService3,ITestService4以及他们的4个实现类。
IServiceCollection container = new ServiceCollection(); container.AddTransient<ITestService1, TestService1>();//瞬时生命周期 container.AddSingleton<ITestService2, TestService2>();//单例:全容器都是一个 container.AddScoped<ITestService3, TestService3>();//请求单例:一个请求作用域是一个实例 container.AddSingleton<ITestService4>(new TestService4());//单例生命周期,在整个进程中获取的是相同实例 var provider = container.BuildServiceProvider(); ITestService1 testService1 = provider.GetService<ITestService1>(); ITestService1 testService2 = provider.GetService<ITestService2>(); Console.WriteLine(object.ReferenceEquals(testService1, testService2));//输出 false ITestService2 testService2_1 = provider.GetService<ITestService2>(); ITestService2 testService2_2 = provider.GetService<ITestService2>(); Console.WriteLine(object.ReferenceEquals(testService2_1, testService2_2));//输出 true ITestService3 testService3_1 = provider.GetService<ITestService3>(); ITestService3 testService3_2 = provider.GetService<ITestService3>(); Console.WriteLine(object.ReferenceEquals(testService3_1, testService3_2));//输出 true var scope1 = provider.CreateScope(); var scope2 = provider.CreateScope(); ITestService3 testService3_3 = scope1.ServiceProvider.GetService<ITestService3>(); ITestService3 testService3_4 = scope2.ServiceProvider.GetService<ITestService3>(); Console.WriteLine(object.ReferenceEquals(testService3_3, testService3_4)); //输出 false ITestService4 testService4_1 = provider.GetService<ITestService4>(); ITestService4 testService4_2 = provider.GetService<ITestService4>(); Console.WriteLine(object.ReferenceEquals(testService4_1, testService4_2)); //输出 true
就从startup.cs中的ConfigureServices方法说起,先来看下定义:
public virtual void ConfigureServices (Microsoft.Extensions.DependencyInjection.IServiceCollection services);
在 ASP.NET Core 中将依赖项注入到控制器
internal class ModuleInit : IModuleInitializer { public void Initialize(IServiceCollection services) { services.AddScoped<ClassOne>(); } }
在 ASP.NET Core 中将依赖项注入到控制器
服务作为构造函数参数添加,并且运行时从服务容器中解析服务。 通常使用接口来定义服务。 例如,考虑需要当前时间的应用。
以下接口公开 IDateTime 服务:
public interface IDateTime { DateTime Now { get; } }
以下代码实现 IDateTime 接口:
public class SystemDateTime : IDateTime { public DateTime Now { get { return DateTime.Now; } } }
将服务添加到服务容器中:
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IDateTime, SystemDateTime>(); services.AddControllersWithViews(); }
以下代码根据一天中的时间向用户显示问候语:
public class HomeController : Controller { private readonly IDateTime _dateTime; public HomeController(IDateTime dateTime) { _dateTime = dateTime; } public IActionResult Index() { var serverTime = _dateTime.Now; if (serverTime.Hour < 12) { ViewData["Message"] = "It's morning here - Good Morning!"; } else if (serverTime.Hour < 17) { ViewData["Message"] = "It's afternoon here - Good Afternoon!"; } else { ViewData["Message"] = "It's evening here - Good Evening!"; } return View(); }
private void RegisterService(IServiceCollection services) { var assembly = Assembly.Load("SmartPro.Admin.Logic"); var allTypes = assembly.GetTypes(); foreach (var type in allTypes) { services.AddSingleton(type); } }
AutoFac也是个容器,下面在Core中把AutoFac整合进来。
在Nuget中添加AutoFac
AutoFac支持AOP
コメント: