当前位置: 首页 > news >正文

渭南哪里做网站石家庄物流网站建设

渭南哪里做网站,石家庄物流网站建设,做的网站如何发布,什么网站可以做外链一、前言这上一篇中#xff0c;主要讲述了什么是IoC容器#xff0c;以及了解到它是DI构造函注入的框架#xff0c;它管理着依赖项的生命周期以及映射关系#xff0c;同时也介绍实践了在ASP.Net Core中,默认提供的内置IoC容器#xff0c;以及它的实例注册方式和相应的生命周… 一、前言这上一篇中主要讲述了什么是IoC容器以及了解到它是DI构造函注入的框架它管理着依赖项的生命周期以及映射关系同时也介绍实践了在ASP.Net Core中,默认提供的内置IoC容器以及它的实例注册方式和相应的生命周期。但考虑到在实际项目中如果需要一个个添加实例会略显麻烦为了达到可以简化我们工作量,因此我们也可以引入其他的Ioc容器框架实现更多的功能和扩展。这里选择用Autofac这也是在.net下比较流行的其他的框架不做说明可自行查阅了解。二、说明AutoFac是一个开源的轻量级的依赖注入容器也是.net下比较流行的实现依赖注入的工具之一。将Autofac整合到你的应用的基本流程如下:按照 控制反转 (IoC) 的思想构建你的应用.添加Autofac引用.在应用的 startup 处创建 ContainerBuilder.注册组件.创建容器,将其保存以备后续使用.应用执行阶段从容器中创建一个生命周期.在此生命周期作用域内解析组件实例.三、开始3.1 默认容器在上一篇中定义的三个接口分别测试SingletonScopeTransient三种一个 TestService服务在内置的IoC容器中在Startup.cs类文件ConfigureServices方法中注入依赖方式如下public void ConfigureServices(IServiceCollection services) {services.AddControllers();services.AddTransientITransientService, TransientService();services.AddSingletonISingletonService, SingletonService();services.AddScopedIScopedService, ScopedService();services.AddScopedITestService, TestService(); } ❝其他不清楚的可以回看上一篇说明❞3.2 Autofac框架现在我们使用其他的IoC容器框架来替换默认的内置IoC这里选择使用Autofac框架「.net core 2.x和3.x 使用autofac注入方式不一样此文章是针对.net core 3.x」首先,我们需要从nuget引用相关的包.「Autofac.Extensions.DependencyInjection」(这个包扩展了一些微软提供服务的类.来方便替换autofac)然后在Program.cs 新增一行代码        public static IHostBuilder CreateHostBuilder(string[] args){//var assemblyName  typeof(Startup).GetTypeInfo().Assembly.FullName;return Host.CreateDefaultBuilder(args).UseServiceProviderFactory(new AutofacServiceProviderFactory())  //设置工厂来替换实例.ConfigureWebHostDefaults(webBuilder {webBuilder.UseStartupStartup();});} UseServiceProviderFactory 设置工厂来替换实例。然后在Startup类增加ConfigureContainer方法在方法中注入依赖    public void ConfigureContainer(ContainerBuilder builder){// Register your own things directly with Autofac, like:builder.RegisterTypeTransientService().AsITransientService();builder.RegisterTypeSingletonService().AsISingletonService().SingleInstance();builder.RegisterTypeScopedService().AsIScopedService().InstancePerLifetimeScope();builder.RegisterTypeTestService().AsITestService().InstancePerLifetimeScope();} ❝说明ASP.NET Core 引入了具有强类型容器配置的能力。 它提供了一个ConfigureContainer方法您可以使用Autofac单独注册而不是使用ServiceCollection注册。使用ConfigureContainer配置在配置WebHostBuilder的Program.Main方法中调用AddAutofac将Autofac挂钩到启动管道中。在Startup类的ConfigureServices方法中使用其他库提供的扩展方法将内容注册到IServiceCollection中。在Startup类的ConfigureContainer方法中将内容直接注册到AutofacContainerBuilder中。❞3.3 测试启动运行项目访问接口/Test效果如下对比之前「默认容器」可以发现在两次的请求访问都一样可以得到了 4个Transient实例2个Scope实例1个Singleton实例。四、说明下面主要针对Autofac中的注册组件、解析服务两大步骤以及其中容器中对应实例的生命周期进行说明。4.1 注册组件通过创建 ContainerBuilder 来注册组件并且告诉容器哪些组件暴露了哪些服务。使用 Register() 方法来注册实现「ContainerBuilder 包含一组 Register() 注册方法而组件暴露服务可用使用 ContainerBuilder 上的 As() 方法。」❝即在容器初始化时候向容器组件添加对象的操作过程。❞通过梳理Autofac所有可用的注册组件方法显示如下图展示的流程图。这里我们只说明下几种便捷的注册方法4.1.1 反射注册直接注册的组件必须是具体的类型并可用暴露抽象和接口作为服务但不能注册一个抽象和接口组件。使用RegisterTypeT()或者RegisterType(typeof(T))方法builder.RegisterTypeTestService().AsITestService(); // 或者 builder.RegisterType(typeof(TestService)).As(typeof(ITestService)) ❝在多个构造函数时如果需要也可手动指定一个构造函数。使用 UsingConstructor 方法和构造方法中代表参数类型的类型。  builder.RegisterTypeTestService().UsingConstructor(typeof(TransientService), typeof(SingletonService)); ❞4.1.2 实例注册提前生成对象的实例并加入容器以供注册组件时使用。使用RegisterInstance()方法// new出一个对象注册 var output  new StringWriter(); builder.RegisterInstance(output).AsTestService(); 如果单例中存在实例且需要在容器中被组件使用时builder.RegisterInstance(MySingleton.Instance).ExternallyOwned(); 4.1.3 Lambda表达式注册当组件创建不再是简单调用构造方法时可用利用lambda表达式来实现一些常规反射无法实现的操作。比如一些复杂参数注册参数注入以及选择参数值实现等。  builder.Register(x  new TransientService()).AsITransientService(); // 或者指定参数builder.Register(x  new TestService(x.ResolveITransientService(), x.ResolveIScopedService(), x.ResolveISingletonService())).AsITestService().InstancePerLifetimeScope(); 4.1.4 泛型注册支持泛型注册操作使用 RegisterGeneric() 方法:builder.RegisterGeneric(typeof(NHibernateRepository)).As(typeof(IRepository)).InstancePerLifetimeScope(); 4.1.5 条件注册在一些特殊场景可能需要通过加上判断条件来决定是否执行该条注册语句。两种方法OnlyIf() - 提供一个表达式, 表示只有满足条件才会执行语句。builder.RegisterTypeManager().AsIManager().OnlyIf(reg reg.IsRegistered(new TypedService(typeof(IService))) reg.IsRegistered(new TypedService(typeof(HandlerB)))); IfNotRegistered() - 表示没有其他服务注册的情况下就执行语句。方法在 ContainerBuilder.Build() 时执行并且以实际组件注册的顺序执行。builder.RegisterTypeServiceA().AsIService(); builder.RegisterTypeServiceB().AsIService().IfNotRegistered(typeof(IService)); 4.1.6 属性注入构造方法参数注入是一种传值给组件的首选的方法。❝在构造函数中是直接使用服务类型作为参数然后AutoFac解析该类时就会去容器内部已存在的组件中查找然后将匹配的对象注入到构造函数中去。❞但你同样也可以使用属性方法注入来传值。❝是将容器内对应的组件直接注入到类内的属性中去,在注册该属性所属类的时候需要使用PropertiesAutowired()方法额外标注。❞「这里不讨论属性注入的好坏也不做说明服务层属性怎么注入只讨论说明控制器中属性如何实现注入」注册组件方法并使用属性注入PropertiesAutowired()标注。builder.RegisterTypeTransientService().AsITransientService().PropertiesAutowired(); 在控制器中使用属性来接收, 「其中注入属性必须标注为public」    [ApiController][Route([controller])]public class TestController : ControllerBase{public ITransientService _transientService { get; set; }  [HttpGet]public JsonResult Get(){var data1    _transientService.GetGuid();return new JsonResult(new { data1});}} 运行测试发现如下发现_transientService为null,所以根本没有注入成功。「这是因为控制器本身的实例以及它的处理是由框架创建和拥有的而不是由容器所有」因此我们需要改变控制器本身的创建及其拥有。在Startup.cs中修改ConfigureServices方法替换从IServiceProvider中解析控制器实例的所有者。        public void ConfigureServices(IServiceCollection services){//替换控制器的所有者services.Replace(ServiceDescriptor.TransientIControllerActivator, ServiceBasedControllerActivator());services.AddControllers();} 注意,替换的方法一定要在AddControllers之前。在ContainerBuilder中通过注册控制器并使用属性注入功能实现.public void ConfigureContainer(ContainerBuilder builder) { //找到所有的controller进行注册并使用属性注入功能var controllerTypesInassembly  typeof(Startup).Assembly.GetExportedTypes().Where(type  typeof(ControllerBase).IsAssignableFrom(type)).ToArray();builder.RegisterTypes(controllerTypesInassembly).PropertiesAutowired();builder.RegisterTypeTransientService().AsITransientService().PropertiesAutowired(); } 这样就可以在Controller中进行属性注入了再次运行查看发现已经成功注入了。4.1.7 程序集注册当我们需要实现批量注册的时候也可以使用程序集的方式来注册这也是常用的方法。❝可通过指定过滤类型服务扫描模块等方式来找到需要注册的组件。❞var assemblies  Assembly.GetExecutingAssembly();builder.RegisterAssemblyTypes(assemblies)//程序集内所有具象类  .Where(c  c.Name.EndsWith(Service)) .PublicOnly()//只要public访问权限的 .Where(cc  cc.IsClass)//只要class型主要为了排除值和interface类型  .AsImplementedInterfaces();//自动以其实现的所有接口类型暴露包括IDisposable接口 说明RegisterAssemblyTypes() 接收包含一个或多个程序集的数组作为参数RegisterAssemblyModules() : 接收模块作为参数进行模块扫描注册PublicOnly() 指定公有方法被注册Where() 要过滤注册的类型Except() 要排除的类型As() 反射出其实现的接口AsImplementedInterfaces() 自动以其实现的所有接口类型暴露包括IDisposable接口4.2 暴露服务上面提到了注册组件时, 我们得告诉Autofac, 组件「暴露」了哪些服务。在上面注册实现中大部分使用到了As() 方法。当然Autofac也提供了其他标注来暴露服务的方法。4.2.1 默认暴露自身类型服务常用的几种方法如下builder.RegisterTypeCallLogger();//不标注默认以自身类型暴露服务 builder.RegisterTypeCallLogger().AsSelf(); builder.RegisterTypeCallLogger().AsCallLogger(); builder.RegisterTypeCallLogger().As(typeof(CallLogger)); 4.2.2 多个暴露服务类型「以其实现的接口interface暴露服务」暴露的类型可以是多个比如CallLogger类实现了ILogger接口和ICallInterceptor接口。❝暴露服务后, 可以解析基于该服务的组件了. 但请注意, 一旦将组件暴露为一个特定的服务, 默认的服务 (组件类型) 将被覆盖。❞所以为了防止被其他服务覆盖可以使用 AsSelf() 方法。Copybuilder.RegisterTypeCallLogger().AsILogger().AsICallInterceptor().AsSelf(); 这样你既可以实现组件暴露一系列特定的服务, 又可以让它暴露默认的服务。4.2.3 程序集注册指定暴露类型可通过指定接口类型暴露服务使用As() 方法publi void ConfigureContainer(ContainerBuilder builder) {builder.RegisterAssemblyTypes(assemblies)//程序集内所有具象类 .Where(cc cc.Name.EndsWith(Repository)|//筛选cc.Name.EndsWith(Service)).As(xx.GetInterfaces()[0])//反射出其实现的接口并指定以其实现的第一个接口类型暴露 } 指定所有实现的接口类型进行暴露❝使用AsImplementedInterfaces()函数实现相当于一个类实现了几个接口interface就会暴露出几个服务等价于上面连写多个As()的作用。❞publi void ConfigureContainer(ContainerBuilder builder) { builder.RegisterAssemblyTypes(asm).Where(t  t.Name.EndsWith(Repository)).AsImplementedInterfaces();//自动以其实现的所有接口类型暴露包括IDisposable接口 } 4.3 解析服务在 注册完组件并暴露相应的服务后, 可以从创建的容器或其生命周期中解析服务。使用 Resolve() 方法来解析实现通过梳理Autofac所有可用的解析服务方法显示如下图展示的流程图。在 注册完组件并暴露相应的服务后, 你可以从创建的容器或其子 生命周期 中解析服务. 让我们使用 Resolve() 方法来实现:var builder  new ContainerBuilder(); builder.RegisterTypeMyComponent().AsIService(); var container  builder.Build();using(var scope  container.BeginLifetimeScope()) {var service  scope.ResolveIService(); } 4.3.1 解析时传参当解析服务时, 需要传参可以使用Resolve() 方法来接受可变长度的参数。可用参数类型❝NamedParameter - 通过名称匹配目标参数TypedParameter - 通过类型匹配目标参数 (需要匹配具体类型)ResolvedParameter - 灵活的参数匹配❞反射组件的参数var reader  scope.ResolveConfigReader(new NamedParameter(configSectionName, pName));Lambda表达式组件的参数不显式调用Resolve传参4.3.2 隐式关系类型❝这里不做详细说明详见官方文档❞4.4 生命周期下面讲下AutoFac定义的几种生命周期作用域并与.NET Core默认的生命周期作了简要的对比。4.4.1 暂时性每次在向服务容器进行请求时都会创建新的实例相当于每次都new出一个。「注册方式」使用InstancePerDependency()方法标注如果不标注这也是默认的选项。以下两种注册方法是等效的//不指定默认就是瞬时的 builder.RegisterTypeTransientService().AsITransientService();//指定其生命周期域为瞬时 builder.RegisterTypeTransientService().AsITransientService().InstancePerDependency(); 「对比」与默认的容器中自带的生命周期AddTransient相同也是每次都是全新的实例。 使用AddTransient()注册 services.AddTransientITransientService, TransientService() 4.4.2 作用域内在每次Web请求时被创建一次实例生命周期横贯整次请求。即在每个生命周期作用域内是单例的。「注册方式」使用InstancePerLifetimeScope()方法标识builder.RegisterTypeScopedService().AsIScopedService().InstancePerLifetimeScope(); 「对比」与默认的容器中自带的生命周期AddScoped相同.NET Core框架自带的容器全权接管了请求和生命周期作用域的创建使用Scoped()可以实现相同的效果。 使用AddScoped()注册 services.AddScopedIScopedService, ScopedService(); 4.4.3 匹配作用域内即每个匹配的生命周期作用域一个实例。 该类型其实是上面的“作用域内”的其中一种可以对实例的共享有更加精准的控制.。我们通过允许给域“打标签”只要在这个特定的标签域内就是单例的。注册 使用InstancePerMatchingLifetimeScope(string tagName)方法注册var builder  new ContainerBuilder(); builder.RegisterTypeWorker().InstancePerMatchingLifetimeScope(myrequest); 当你开始一个生命周期时, 提供的标签值和它就关联起来了。解析// myrequest标签子域一 using(var scope1  container.BeginLifetimeScope(myrequest)) {for(var i  0; i  100; i){var w1  scope1.ResolveWorker();using(var scope2  scope1.BeginLifetimeScope()){var w2  scope2.ResolveWorker();//解析了2次但2次都是同一个实例w1和w2指向同一个内存块Ⅰ}} }// //myrequest标签子域二 using(var scope3  container.BeginLifetimeScope(myrequest)) {for(var i  0; i  100; i){//因为标签域内已注册过所以可以解析成功var w3  scope3.ResolveWorker();using(var scope4  scope3.BeginLifetimeScope()){var w4  scope4.ResolveWorker();//因为和上面不是同一个子域,所以解析出的实例w3, w4是同一个实例但与之前的w1, w2并不是同一个实例 }} }//无标签子域三 using(var noTagScope  container.BeginLifetimeScope()) {// 如果你尝试从一个名称并不匹配的生命周期中解析一个每个匹配生命周期作用域的组件你会得到一个异常!var fail  noTagScope.ResolveWorker(); } ❝如果你尝试从一个名称并不匹配的生命周期中解析一个每个匹配生命周期作用域的组件你会得到一个异常!❞4.4.4 全局单例即全局只有一个实例即每一个后续请求都使用同一个实例。「注册方式」使用SingleInstance()方法标识 builder.RegisterTypeSingletonService().AsISingletonService().SingleInstance() 「对比」与默认的容器中自带的生命周期AddSingleton相同。 使用AddSingleton();注册services.AddSingletonISingletonService, SingletonService(); ❝还有其他生命周期补充每个请求一个实例(Instance Per Request) 其实是一种的“匹配作用域内单例”的一种。每次被拥有一个实例(Instance Per Owned)线程作用域(Thread Scope)这几种在这不做详细说明具体可以查看官网。❞4.5 小结在.NET Core中默认的容器自带生命周期只有3种类型而相比于autofac其显得更加丰富复杂些。五、总结本篇主要介绍autofac框架的使用从注册组件到暴露服务及解析服务的各个过程。同时也与.NET Core框架默认容器相比更加丰富了一些注册方法和更复杂的生命周期在应用上也更加轻巧快捷特别是在批量注册上更显实用。文章展示的思维导图❝https://www.processon.com/view/link/6072ed8863768912ae50b483❞参考资料Autofac官方网站❝https://autofaccn.readthedocs.io/en/latest/getting-started/index.html❞好啦这篇文章就先讲述到这里吧希望对大家有所帮助。如果有不对的或不理解的地方希望大家可以多多指正提出问题一起讨论,不断学习,共同进步。????
http://wiki.neutronadmin.com/news/442604/

相关文章:

  • 关于小说网站的一些建设流程百度网盘提取码入口
  • 设计工作室网站网站上的3d怎么做的
  • 更改网站后台网站建设如何制作教程
  • 枣庄高端网站建设织梦网站联系我们的地图怎么做
  • 中国保密在线网站培训系统展示型的网站开发价格
  • 电子商务网站开发指南如何使用wordpress插件
  • 好网站推荐的网站wordpress 5.1.1漏洞
  • 做动画 的 网站有哪些软件建一个网站需要多少钱?
  • 仿珠宝首饰网站开发购物网站导航模板
  • 花钱也可以哪些网站可以做推广广告自己做电商网站
  • seo如何优化一个网站住房和城乡建设部令第37号
  • 网站目录做301wordpress编辑器上传图片
  • 网站设计开发的难点高校思政网站建设意义
  • pathon做网站wordpress 页面 文章 区别
  • 海珠哪家网站建设好本科自考多少钱
  • win10 中国建设银行网站古冶区城乡建设局网站
  • 门头沟建设网站用vue做pc端网站
  • 实训报告网站开发室内设计软件免费下载
  • [8dvd]flash网站源文件 flash整站源码北京商场购物中心
  • 网站怎么开启gzip珠海网站建设网络公司
  • 简单的网站开发的软件有哪些dw可以做有后台的网站么
  • 官方网站内容可做证据吗wordpress按地区
  • 建建设网站广东金东建设工程公司网站
  • 12306网站建设超30亿设计专业大学排名
  • 制作网站的发展前景wordpress 快报插件
  • dw做的网站怎样才有域名网站制作高端网站建设
  • 中国站长之家爱站网门户网站功能清单
  • 建设蒙古语网站重庆建筑网站
  • 织梦自定义表单做网站在线留言做矿产公司的网站
  • 地信网站建设网络推广培训心得