上海一实仪器设备厂,欧陆经典女鞋,留夏英文版
asp.net core依赖注入解读&使用autofac替代实现 1. 前言 2. asp.net core 中的di方式 3. autofac实现和自定义实现扩展方法 3.1 安装autofac 3.2 创建容器并注册依赖关于ioc模式(控制反转)和di技术(依赖注入),我们已经见过很多的探讨,这里就不再赘述了。比如说必看的martin fowler《ioc 容器和 dependency injection 模式》,相关资料链接都附于文章末尾。其中我非常赞同artech的说法"控制更多地体现为一种流程的控制",而依赖注入技术让我们的应用程序实现了松散耦合。
asp.net core本身已经集成了一个轻量级的ioc容器,开发者只需要定义好接口后,在startup.cs的configureservices方法里使用对应生命周期的绑定方法即可,常见方法如下
services.addtransient services.addscoped services.addsingleton
对于上述的三种di注入方式,官方也给出了详细的解释,我来简单翻译一下
transient在这之后,我们便可以将服务通过构造函数注入或者是属性注入的方式注入到controller,view(通过使用@inject),甚至是filter中(以前使用unity将依赖注入到filter真是一种痛苦)。话不多说,先来体验一把
tips:startup.cs是什么,详见asp.net core 介绍和项目解读
大多项目举例依赖注入的生命周期演示时,都会采取可变guid来作为返回显示,此次示例也会这样处理。我们先定义一个iguidappservice接口,里面定义基接口和三种注入模式的接口
public interface iguidappservice { guid guiditem(); } public interface iguidtransientappservice : iguidappservice { } public interface iguidscopedappservice : iguidappservice { } public interface iguidsingletonappservice : iguidappservice { }
同样的,在guidappservice中定义其实现类。这里为了直观显示每次请求的返回值,采取如下代码
public class guidappservicebase : iguidappservice { private readonly guid _item; public guidappservicebase() { _item = guid.newguid(); } public guid guiditem() { return _item; } } public class guidtransientappservice : guidappservicebase, iguidtransientappservice { } public class guidscopedappservice : guidappservicebase, iguidscopedappservice { } public class guidsingletonappservice : guidappservicebase, iguidsingletonappservice { }
最后是controller和view视图的代码
# controller public class homecontroller : controller { private readonly iguidtransientappservice _guidtransientappservice; //#构造函数注入 //private iguidtransientappservice _guidtransientappservice { get; } #属性注入 private readonly iguidscopedappservice _guidscopedappservice; private readonly iguidsingletonappservice _guidsingletonappservice; public homecontroller(iguidtransientappservice guidtransientappservice, iguidscopedappservice guidscopedappservice, iguidsingletonappservice guidsingletonappservice) { _guidtransientappservice = guidtransientappservice; _guidscopedappservice = guidscopedappservice; _guidsingletonappservice = guidsingletonappservice; } public iactionresult index() { viewbag.transientitem = _guidtransientappservice.guiditem(); viewbag.scopeditem = _guidscopedappservice.guiditem(); viewbag.singletonitem = _guidsingletonappservice.guiditem(); return view(); } } # index view guiditem shows transientitem: @viewbag.transientitem scopeditem: @viewbag.scopeditem singletonitem: @viewbag.singletonitem
之后我们打开两个浏览器,分别刷新数次,也只会发现“transientitem”和“scopeditem”的数值不断变化,“singletonitem”栏的数值是不会有任何变化的,这就体现出单例模式的作用了,示例图如下
但是这好像还不够,要知道我们的scoped的解读是“生命周期横贯整次请求”,但是现在演示起来和transient好像没有什么区别(因为两个页面每次浏览器请求仍然是独立的,并不包含于一次中),所以我们采用以下代码来演示下(同一请求源)
# 新建guiditempartial.cshtml视图,复制如下代码,使用@inject注入依赖 @using dependencyinjection.iapplicationservice @inject iguidtransientappservice transientappservice @inject iguidscopedappservice guidscopedappservic @inject iguidsingletonappservice guidsingletonappservice guiditem shows transientitem: @transientappservice.guiditem() scopeditem: @guidscopedappservic.guiditem() singletonitem: @guidsingletonappservice.guiditem() # 原先的index视图 @{ viewdata["title"] = "home page"; } @html.partial("guiditempartial") @html.partial("guiditempartial")
依然是 ctrl+f5 调试运行,可以发现“scopeditem”在同一请求源中是不会发生变化的,但是“transientitem”依然不断变化,理论仍然是支持的
除了asp.netcore自带的ioc容器外,我们还可以使用其他成熟的di框架,如autofac,structuremap等(笔者只用过unity,ninject和castle,castle也是使用abp时自带的)。
首先在project.json的dependency节点中加入autofac.extensions.dependencyinjection引用,目前最新版本是4.0.0-rc3-309
在startup.cs中创建一个public icontainer applicationcontainer { get; private set; }对象,并把configureservices返回类型改为iserviceprovider,然后复制以下代码进去,也可以实现相关功能
var builder = new containerbuilder(); //注意以下写法 builder.registertype().as(); builder.registertype().as().instanceperlifetimescope(); builder.registertype().as().singleinstance(); builder.populate(services); this.applicationcontainer = builder.build(); return new autofacserviceprovider(this.applicationcontainer);
创建autofac容器时不要忘了将configureservices的返回值修改为iserviceprovider 对应asp.net core提及的不同的生命周期,autofac也定义了对应的扩展方法,如instanceperlifetimescope等,默认为transient模式,包括entityframwork等context也是该种模式 autofac core不支持从view中注入,但是可以和asp.net core自带ioc容器配合使用 autofac core版本和传统的asp.net mvc项目版本的区别值得注意的几点:
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Net Core Web Api项目与在NginX下发布的方法
asp.net core3.1 引用的元包dll版本兼容性问题解决方案
IdentityServer4实现.Net Core API接口权限认证(快速入门)
ASP.NET Core MVC通过IViewLocationExpander扩展视图搜索路径的实现
网友评论