河北网站优化公司乐清做网站的公司有哪些
news/
2025/9/23 4:11:42/
文章来源:
河北网站优化公司,乐清做网站的公司有哪些,如何用织梦做网站,岳池发展建设集团有限公司门户网站一. 说在前面的话 凡是大约工作在两年以上的朋友们#xff0c;或多或少都会接触到一些框架搭建方面的知识#xff0c;只要一谈到框架搭建这个问题或者最佳用法这个问题#xff0c;势必会引起一点点小小的风波#xff0c;我说我的好#xff0c;他说他的好#xff0c;非常容…一. 说在前面的话 凡是大约工作在两年以上的朋友们或多或少都会接触到一些框架搭建方面的知识只要一谈到框架搭建这个问题或者最佳用法这个问题势必会引起一点点小小的风波我说我的好他说他的好非常容易骂架所以在本节乃至该系列我仅仅是总结了一下自己日常中的一些用法谈一下自己浅陋的见解谈不上最佳只要不误导新手 能有点帮助作用就可以了如您不喜欢请“右上角 谢谢”。 在框架搭建过程中在层与层的解耦方面势必会涉及到IOC框架.Net 平台下我用过的IOC框架主要是 Spring.Net 、Unity、AutoFac当然还有Castle我没用过就不发表任何评论了 在用过的IOC框架中Spring.Net 相对很老了貌似在2015年就不在更新了但基本的功能也够用了。 现阶段用的最多的就是Unity和AutoFac了版本更新也比较快Unity大约一年前写过两篇文章了本次在该框架系列也会考虑更新一下Unity本节主要介绍一下AutoFac的几个基本用法。 先说一下两个概念IOC和DI我的理解 ① IOC调用者不再创建(不自己new)被调用者的实例而是交给容器去创建(AutoFac就充当这里的容器)这就是控制反转。 ② DI容器创建好的实例再注入调用者的过程就是依赖注入比如属性注入、构造函数注入等。
AutoFac的信息 ① 官网地址https://autofac.org/ ② 官方文档http://autofac.readthedocs.io/en/latest/index.html ③ 最新版本4.8.1 (截止2018-08-21) 本节的内容主要包括 1. 在使用IOC框架之前的几种创建对象的方式。 2. AutoFac的基本用法和几种生命周期。 3. AutoFac和Asp.Net MVC5进行整合利用属性的方式进行注入。
事先说明一下本节要用到的实现类和接口类
(1). Ypf.BLL层中包括CatBLL、DogBLL、RoleBLL、UserBLL。 CatBLL DogBLL RoleBLL UserBLL
(2). Ypf.IBLL层包括IAnimalBLL、IPeopleBLL、IRoleBLL、IUserBLL。 IAnimalBLL IPeopleBLL IRoleBLL IUserBLL 二. 引入IOC框架之前的几个写法
1. 最原始的方式直接new(需添加对BLL层的引用)
1 {
2 UserBLL userBll new UserBLL();
3 var result1 userBll.GetUserInfor();
4 Console.WriteLine(result1);
5 } 2. 面向接口编程(仍需添加对BLL层的引用)
1 {
2 IUserBLL userBll new UserBLL();
3 var result1 userBll.GetUserInfor();
4 Console.WriteLine(result1);
5 } 3. 接口反射(只需将BLL层的程序集拷贝进来) 1 {2 Assembly ass Assembly.Load(Ypf.BLL);3 Type type ass.GetType(Ypf.BLL.UserBLL);4 //调用默认的无参构造函数进行对象的创建5 object myUserBLL Activator.CreateInstance(type);6 IUserBLL userBLL (IUserBLL)myUserBLL;7 var result1 userBLL.GetUserInfor();8 Console.WriteLine(result1);9
10 } 4. 手写IOC(反射简单工厂配置文件)【需将BLL层的程序集拷贝进来】 配置文件代码 appSettings!--直接修改配置文件可以切换IUserBLL的实现类发布后可以直接通过改配置文件,代码什么也不用改,体会反射面向接口编程--add keyDllName valueYpf.BLL/add keyClassName valueYpf.BLL.UserBLL//appSettings
简单工厂代码 1 /// summary2 /// 简单工厂隔离对象的创建3 /// /summary4 public class SimpleFactory5 {6 private static string DllName ConfigurationManager.AppSettings[DllName];7 private static string ClassName ConfigurationManager.AppSettings[ClassName];8 public static IUserBLL CreateInstance()9 {
10 Assembly ass Assembly.Load(DllName);
11 Type type ass.GetType(ClassName);
12 object obj Activator.CreateInstance(type);
13 return (IUserBLL)obj;
14 }
15 } 调用代码
1 {
2 IUserBLL userBLL SimpleFactory.CreateInstance();
3 var result userBLL.GetUserInfor();
4 Console.WriteLine(result);
5 } 三. AutoFac常见用法总结
1. 基本用法 同时添加对Ypf.BLL层和Ypf.IBLL层的引用然后 声明容器→注册实例→解析对象→调用方法、进行测试代码如下 1 {
2 ContainerBuilder builder new ContainerBuilder();
3 //把UserBLL注册为IUserBLL实现类,当请求IUserBLL接口的时候返回UserBLL对象
4 builder.RegisterTypeUserBLL().AsIUserBLL();
5 IContainer resolver builder.Build();
6 IUserBLL userBLL resolver.ResolveIUserBLL();
7 var result1 userBLL.GetUserInfor();
8 Console.WriteLine(result1);
9 } 评价这种用法单纯的是为了介绍AutoFac中的几个方法仅此而已在实际开发没有这么用的坑比用法起不到任何解耦的作用。 2. AsImplementedInterfaces的用法 在很多情况下一个类可能实现了多个接口 如果我们通过 builder.RegisterTypexxxBLL().AsIxxxBLL(); 这种方式按部就班排着把这个类注册给每个接口实现几个接口就要写几行注册代码很繁琐我们可以通过 AsImplementedInterfaces() 方法可以把一个类注册给它实现的全部接口。 这样的话想用哪个接口通过Resolve解析即可代码如下 1 {2 ContainerBuilder builder new ContainerBuilder();3 //这样请求UserBLL实现的任何接口的时候都会返回 UserBLL 对象。4 builder.RegisterTypeUserBLL().AsImplementedInterfaces();5 IContainer resolver builder.Build();6 IUserBLL iUserBLL resolver.ResolveIUserBLL();7 IPeopleBLL iPeopleBLL resolver.ResolveIPeopleBLL();8 9 var r1 iUserBLL.GetUserInfor();
10 var r2 iPeopleBLL.Introduce();
11
12 Console.WriteLine(r1);
13 Console.WriteLine(r2);
14 } 评价同时添加对Ypf.BLL层和Ypf.IBLL层的引用这里也是单纯的为了介绍AsImplementedInterfaces()的用法还是存在实现类的身影在实际开发中没有这么用的起不到任何解耦的作用坑比用法。 3. AutoFac反射(彻底消灭实现类) 引入反射的背景前面两种方式都需要添加对Ypf.BLL层的引用麻烦的要死根本没有什么改观还是紧耦合在一起。并且如果有很多接口和实现类的话用RegisterType一行一行的去写累个半死在这种情况下引入反射的概念简化代码量代码如下 1 {2 ContainerBuilder builder new ContainerBuilder();3 //加载实现类的程序集4 Assembly asm Assembly.Load(Ypf.BLL);5 builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces();6 IContainer resolver builder.Build();7 8 IUserBLL userBLL resolver.ResolveIUserBLL();9 IPeopleBLL peopleBLL resolver.ResolveIPeopleBLL();
10 var r1 userBLL.GetUserInfor();
11 var r2 peopleBLL.Introduce();
12
13 Console.WriteLine(r1);
14 Console.WriteLine(r2);
15 } 评价彻底摆脱了实现类的身影与Ypf.BLL层进行了解耦只需要添加对Ypf.IBLL层的引用但需要把Ypf.BLL的程序集拷贝到AutoFacTest项目下。
小小的升级一下 把反射那个程序集类写到配置文件中然后在代码中通过读取配置文件进行进一步的反射代码如下
1 appSettings
2 add keyDllName valueYpf.BLL/
3 /appSettings 1 {2 ContainerBuilder builder new ContainerBuilder();3 //加载实现类的程序集4 string DllName ConfigurationManager.AppSettings[DllName];5 Assembly asm Assembly.Load(DllName);6 builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces();7 IContainer resolver builder.Build();8 9 IUserBLL userBLL resolver.ResolveIUserBLL();
10 IPeopleBLL peopleBLL resolver.ResolveIPeopleBLL();
11 var r1 userBLL.GetUserInfor();
12 var r2 peopleBLL.Introduce();
13
14 Console.WriteLine(r1);
15 Console.WriteLine(r2);
16 } 4. PropertiesAutowired(属性的自动注入) 背景一个实现类中定义了其他类型的接口属性比如RoleBLL中定义IUserBLL的接口属性而且要对其进行调用 这个时候就需要通过PropertiesAutowired实现属性的自动注入了。 注只有通过AutoFac创建的对象才能实现属性的自动注入!! 相关的类、接口要是public类型。 RoleBLL 1 {2 ContainerBuilder builder new ContainerBuilder();3 //加载实现类的程序集4 Assembly asm Assembly.Load(Ypf.BLL);5 builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired();6 IContainer resolver builder.Build();7 8 IRoleBLL iRoleBLL resolver.ResolveIRoleBLL();9 var r1 iRoleBLL.ShowDIDemo();
10 Console.WriteLine(r1);
} 下面测试一下不是AutoFac创建的对象能否实现属性的自动注入新建TempTest类在里面声明IUserBLL属性并且在方法中进行调用然后new一个TempTest对象对该showMsg方法进行调用发现报空指针错误说明userBLL属性为空没能自动注入。 1 public class TempTest
2 {
3 public IUserBLL userBLL { get; set; }
4
5 public void showMsg()
6 {
7 Console.WriteLine(userBLL.GetUserInfor());
8 }
9 } 1 //测试自己new的对象不能实现属性的自动注入
2 //下面代码报空指针错误
3 {
4 TempTest t new TempTest();
5 t.showMsg();
6 } 5. 1个接口多个实现类的情况 背景1个接口有多个实现类的情况(DogBLL 和 CatBLL 都实现了 IAnimalBLL接口) 分析resolver.ResolveIAnimalBLL();只会返回其中一个类的对象 解决方案如果想返回多个实现类的对象改成 resolver.ResolveIEnumerableIAnimalBLL()即可。 1 {2 ContainerBuilder builder new ContainerBuilder();3 //加载实现类的程序集4 Assembly asm Assembly.Load(Ypf.BLL);5 builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired();6 IContainer resolver builder.Build();7 8 //返回 CalBLL 和 DogBLL 中的一个9 //{
10 // IAnimalBLL iAnimalBLL resolver.ResolveIAnimalBLL();
11 // var r1 iAnimalBLL.Introduce();
12 // Console.WriteLine(r1);
13 //}
14
15 //如何获取多个呢
16 {
17 IEnumerableIAnimalBLL blls resolver.ResolveIEnumerableIAnimalBLL();
18 foreach (IAnimalBLL animalBLL in blls)
19 {
20 Console.WriteLine(animalBLL.GetType());
21 Console.WriteLine(animalBLL.Introduce());
22 }
23 }
24 } 6. AutoFac的几种常见生命周期
1. InstancePerDependency每次请求 Resovle都返回一个新对象。InstancePerDependency()【这也是默认的创建实例的方式。】
2. SingleInstance 单例只有在第一次请求的时候创建 。SingleInstance()
3. InstancePerRequestASP.Net MVC 专用每次http请求内一个对象也可以理解为一个方法内。InstancePerRequest() 和 CallContext神似
4. InstancePerLifetimeScope在一个生命周期域中每一个依赖或调用创建一个单一的共享的实例且每一个不同的生命周期域实例是唯一的不共享的。 下面测试一下前两种生命周期 情况1 1 {2 ContainerBuilder builder new ContainerBuilder();3 //加载实现类的程序集4 Assembly asm Assembly.Load(Ypf.BLL);5 builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired().InstancePerDependency();6 IContainer resolver builder.Build();7 8 IUserBLL u1 resolver.ResolveIUserBLL();9 IUserBLL u2 resolver.ResolveIUserBLL();
10
11 Console.WriteLine(object.ReferenceEquals(u1, u2));
12
13 } 结果False证明InstancePerDependency 每次都创建一个新对象
情况2 1 {2 ContainerBuilder builder new ContainerBuilder();3 //加载实现类的程序集4 Assembly asm Assembly.Load(Ypf.BLL);5 builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired().SingleInstance();6 IContainer resolver builder.Build();7 8 IUserBLL u1 resolver.ResolveIUserBLL();9 IUserBLL u2 resolver.ResolveIUserBLL();
10
11 Console.WriteLine(object.ReferenceEquals(u1, u2));
12
13 } 结果true证明SingleInstance 每次都返回同一个对象。 四. AutoFac与MVC整合
1. Controller中通过属性注入对象 步骤1在Ypf.MVC层中添加对Ypf.IBLL层的引用并将Ypf.BLL的程序集拷贝到 Ypf.MVC中或者直接改一下Ypf.BLL输出路径。 步骤2通过Nuget安装程序集 Autofac.Mvc5。 步骤3在Gloabl 注册 AutoFac代码。 1 public class MvcApplication : System.Web.HttpApplication2 {3 protected void Application_Start()4 {5 AreaRegistration.RegisterAllAreas();6 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);7 RouteConfig.RegisterRoutes(RouteTable.Routes);8 BundleConfig.RegisterBundles(BundleTable.Bundles);9
10 /***********下面是AutoFac的注册*************/
11 //1. 创建容器
12 var builder new ContainerBuilder();
13 //2. 把当前程序集中的所有Controller都注册进来
14 builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
15 //3. 把Ypf.BLL中的所有类注册给它的全部实现接口并且把实现类中的属性也进行注册
16 //{ Assembly asmService Assembly.Load(Ypf.BLL); }
17 //PS这里可以配合配置文件的将Ypf.BLL写到配置文件中
18 string DllName ConfigurationManager.AppSettings[DllName];
19 Assembly asmService Assembly.Load(DllName);
20 builder.RegisterAssemblyTypes(asmService).Where(t !t.IsAbstract).AsImplementedInterfaces().PropertiesAutowired();
21 var container builder.Build();
22 //4. 下面这句话表示当mvc创建controller对象的时候都是由AutoFac为我们创建Controller对象
23 DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
24
25
26 }
27 } PS分享个小技巧 步骤4在Controller中进行调用。 2. 普通类中通过代码获取对象 在一个没有通过AutoFac注册的普通类中如何获取接口对象呢通过DependencyResolver.Current.GetServiceIUserBLL();来获取。 代码如下 1 public class Utils
2 {
3 public static string Test()
4 {
5 IUserBLL userBLL DependencyResolver.Current.GetServiceIUserBLL();
6 return userBLL.GetUserInfor();
7 }
8 } 3. 如何在普通类中通过属性的方式注入对象
需要有两个条件 ①: 这个普通类的创建必须在Global中通过AutoFac来进行注册。 ②: 获取这个类的时候必须通过 DependencyResolver.Current.GetServiceIUserBLL(); 这种方式来获取。 在Global文件中注册该普通类 该普通类CommonHelp的获取必须通过DependencyResolver.Current.GetServiceCommonHelp();方式来获取。 4. 在单独线程中获取对象 比如在Quartz.Net 中需要通过下面代码来获取。 详细代码如下 {//1.创建作业调度池(Scheduler)IScheduler scheduler StdSchedulerFactory.GetDefaultScheduler();//2.创建一个具体的作业即job (具体的job需要单独在一个文件中执行)var job JobBuilder.CreateHelloJob().Build();//3.创建并配置一个触发器即trigger 1s执行一次var trigger TriggerBuilder.Create().WithSimpleSchedule(x x.WithIntervalInSeconds(1).RepeatForever()).Build();//4.将job和trigger加入到作业调度池中scheduler.ScheduleJob(job, trigger);//5.开启调度scheduler.Start();
} 1 public class HelloJob:IJob2 {3 void IJob.Execute(IJobExecutionContext context)4 {5 IUserBLL userBLL;6 var container AutofacDependencyResolver.Current.ApplicationContainer;7 using (container.BeginLifetimeScope())8 {9 userBLL container.ResolveIUserBLL();
10 }
11 //下面代码只是测试
12 Console.WriteLine(userBLL.GetUserInfor());
13 }
14 }
!
作 者 : Yaopengfei(姚鹏飞)博客地址 : http://www.cnblogs.com/yaopengfei/声 明1 : 本人才疏学浅用郭德纲的话说“我是一个小学生”如有错误欢迎讨论请勿谩骂^_^。声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址否则保留追究法律责任的权利。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/911321.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!