电子商务网站开发数据库表格,深圳有几个区地图,wordpress the_content(),wordpress缓存设置本节内容为控制反转与依赖注入简介控制反转IOC这个内容事实上在我们的C#高级篇就已经有所讲解#xff0c;控制反转是一种设计模式#xff0c;你可以这样理解控制反转#xff0c;假设有一个人他有一部A品牌手机#xff0c;他用手机进行听歌、打游戏#xff0c;那么你可以创… 本节内容为控制反转与依赖注入简介控制反转IOC这个内容事实上在我们的C#高级篇就已经有所讲解控制反转是一种设计模式你可以这样理解控制反转假设有一个人他有一部A品牌手机他用手机进行听歌、打游戏那么你可以创建一个手机类和一个人类class APhone : IPhone
{public string Owner{get;set;}public Phone(string own){Owner own;}void Play(){}void Music(){}
}
class Man
{public string Name{get;set;}void Game(){var p new APhone(Name);p.Play();}
}事实上这段代码的耦合度是比较高的它使用的是正转也就是我需要什么东西的时候我就自己创建一个这个东西。为什么说他不好呢如果有一天这个人决定再也不使用A品牌手机了他决定以后只使用B品牌。那么也就意味着整个的Man类使用过APhone类的地方都需要更改。这是一个非常麻烦的事情我们这个时候就需要运用我们的IOC控制反转了。我们将实例或者是需要使用的对象的创建交给你的调用者自己只负责使用其它人丢给你依赖的这个过程理解为注入。控制反转的核心就是——原本我保存使用我自己的东西现在我把控制权交给我的上级我需要使用的时候再向他要。这个时候接口的作用不言而喻A继承了Phone接口B也继承了假定我们一开始就使用Phone接口去创建不同的AB对象那么是不是可以有效的切换AB对象呢依赖注入依赖注入体现的是一个IOC控制反转它非常的简单我们之前的Man类代码中使用的是正转的方式也就是我要一个对象那么我就创建一个。现在我们使用依赖注入就是将我们对这个对象的控制权交给上一级接口也就成为了这种我想要一个对象我就向上级发出请求上级就给我创建了一个对象。我们通常使用构造函数注入的方式进行依赖的注入。上文的代码就会变成class Man
{private readonly IPhone _phone;public Man(IPhone phone){_phone phone;}
}假设这个时候你需要将手机换成B品牌那么只需要再注入的地方传入B品牌的对象即可了。容器但是现在又出现了一个新的问题假设说这个类有100个使用该接口的依赖如果我们是不是要在100个地方做这样的事情控制是反转了依赖的创建也移交到了外部。现在的问题是依赖太多我们需要一个地方统一管理系统中所有的依赖这个时候我们就使用容器进行集中的管理容器负责两件事情绑定服务与实例之间的关系获取实例并对实例进行管理创建与销毁使用说了那么多我们如何在.NET Core中使用我们的依赖注入呢这里我们针对的是所有的.NET Core的应用在.NET Core中依赖注入的核心分为两个组件位于Microsoft.Extensions.DependencyInjection命名空间下的IServiceCollection和 IServiceProvider。其中IServiceCollection 负责注册IServiceProvider 负责提供实例在默认的容器ServiceCollection中有三个方法.AddTransientI,C().AddSingletonI,C().AddScopedI,C()这里就不得不提一下我们依赖注入的三种生命周期了Singleton指的是单例模式也就是说在整个程序运转期间只会生成一次Transient指每一次GetService都会创建一个新的实例Scope指在同一个Scope内只初始化一个实例 可以理解为 每一个request级别只创建一个实例同一个http request会在一个 scope内我们可以尝试使用控制台项目来模拟依赖注入的原理也就是说我们直接从容器获取我们对象实例并且我们使用Guid进行唯一性的标记。interface IPhoneScope{Guid Guid { get; }}interface IPhoneSingleton{Guid Guid { get; }}interface IPhoneTransient{Guid Guid { get; }}class PhoneService:IPhoneScope,IPhoneSingleton,IPhoneTransient{public PhoneService(){this._guid Guid.NewGuid();}public PhoneService(Guid guid){this._guid guid;}private Guid _guid;public Guid Guid gt; this._guid;}然后在我们的主函数中namespace DI_AND_IOC
{class Program{static void Main(string[] args){var services new ServiceCollection().AddScopedlt;IPhoneScope, PhoneServicegt;().AddTransientlt;IPhoneTransient, PhoneServicegt;().AddSingletonlt;IPhoneSingleton, PhoneServicegt;();var provider services.BuildServiceProvider();using (var scope provider.CreateScope()){var p scope.ServiceProvider;var scopeobj1 p.GetServicelt;IPhoneScopegt;();var transient1 p.GetServicelt;IPhoneTransientgt;();var singleton1 p.GetServicelt;IPhoneSingletongt;();var scopeobj2 p.GetServicelt;IPhoneScopegt;();var transient2 p.GetServicelt;IPhoneTransientgt;();var singleton2 p.GetServicelt;IPhoneSingletongt;();Console.WriteLine($scope1: {scopeobj1.Guid},\n $transient1: {transient1.Guid}, \n $singleton1: {singleton1.Guid}\n);Console.WriteLine($scope2: {scopeobj2.Guid}, \n $transient2: {transient2.Guid},\n $singleton2: {singleton2.Guid}\n);}using (var scope provider.CreateScope()){var p scope.ServiceProvider;var scopeobj3 p.GetServicelt;IPhoneScopegt;();var transient3 p.GetServicelt;IPhoneTransientgt;();var singleton3 p.GetServicelt;IPhoneSingletongt;();Console.WriteLine($scope3: {scopeobj3.Guid}, \n $transient3: {transient3.Guid},\n $singleton3: {singleton3.Guid});}}}
}你应该会得到类似以下的数据scope1: 096d38e5-0c7b-4e50-9c79-241fb18a56ed,
transient1: 289ebd11-8159-4f22-b53e-ed738a317313,
singleton1: b453b7f5-3594-4b66-99c8-a72763abaa83scope2: 096d38e5-0c7b-4e50-9c79-241fb18a56ed,
transient2: 212ad420-e54c-4dd6-9214-abe91aacdd9c,
singleton2: b453b7f5-3594-4b66-99c8-a72763abaa83scope3: 688b6ffd-a8c1-47f4-a20a-872c2285d67c,
transient3: 3d09997d-fffb-43d1-9e53-ccf9771c819d,
singleton3: b453b7f5-3594-4b66-99c8-a72763abaa83可以发现singleton对象是不会发生改变的而scope对象在创建新的scope之后就发生了改变而transient对象每一次请求都在发生改变。需要注意的是在控制台项目使用容器服务需要引入 *** Microsoft.Extensions.DependencyInjection *** 程序集你可以在引入中导入该dll通过对注入服务的生命周期管控在一些ASP.NET Core项目中有些类服务有可能跨越了多个Action或者Controller那么我们正确的使用生命周期我们可以尽可能的节省内存即能减少实例初始化的消耗。在ASP.NET Core中的使用在ASP.NET Core中我们使用依赖注入非常的简单在StartUp类中的ConfigureServices方法中已经为我们构建好了容器我们只需要做类似于这样的操作services.AddScopedlt;IPhoneScope, PhoneServicegt;();
services.AddDbContextlt;DbContextgt;();
services.AddMVC();如果你需要在控制器中注入服务官方的推荐方案是使用构造函数注入public IPhoneScope _ips;
public Controller(IPhoneScope ips)
{_ips ips;
}特别的你如果使用MVC的Razor页面进行注入的话那么输入以下指令如果我的文章帮助了您请您在github.NETCoreGuide项目帮我点一个star在博客园中点一个关注和推荐。