Spring.Net —IOC详解
一. Spring.net中IOC介绍
1. 什么是IOC,控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
二. Spring.Net基本实现:此处使用的是把引用外部的xml文件封装object里的代码。
实现步骤,
1. 首先引用两个dll文件,从 Spring.net2.0中找出这四个文件,并且放在新建的Lib文件夹中,然后导入文件。
引入文件 :
2. 新建一个接口,并且提供一个方法。
1 namespace SpringNet 2 { 3 public interface IUserInfoService 4 { 5 string msgShow(); 6 } 7 }
3. 写一个类,继承上面的接口
1 { 2 public class UserInfoService : IUserInfoService 3 { 4 public string UserName { get; set; } 5 public PerSon person { get; set; } 6 public string msgShow() 7 { 8 return "hello:" + UserName+",年龄:"+person.Age; 9 } 10 } 11 }
3.5 加一个person类,后面ref对应的类
1 namespace SpringNet 2 { 3 public class PerSon 4 { 5 public int Age { get; set; } 6 } 7 }
4 .新建一个winform页面,并且放一个button按钮
5. 配置配置文件,重点看红色标记的行,其中value是是指当前属性的值,而ref是指关联的类的名称。
重点注意一下:命名空间和类名很有可能不是同一个
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <configSections> 4 <sectionGroup name="spring"> <!--配置引用的dll文件的路径--> 5 <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/> 6 <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> 7 <!--配置截止--> 8 </sectionGroup> 9 </configSections> 10 <spring> 11 <context> 12 <resource uri="config://spring/objects"/> 13 <!--将xml与配置文件关联--> 14 <!-- <resource uri="file://XMLServer.xml"/> --> 15 </context> 16 <objects xmlns="http://www.springframework.net"> 17 18 <!--使用xml文件--> 19 <description>An example that demonstrates simple IoC features.</description> 20 <!--命名空间的类全称,和程序集的名称--> 21 <object name="UserInfoService" type="SpringNet.UserInfoService, SpringNet"> 22 <!--类的属性--> 23 <property name="UserName" value="张三"/> 24 <property name="person" ref="PerSon"/> 25 26 <!--类的属性--> 27 </object> 28 <object name="PerSon" type="SpringNet.PerSon, SpringNet"> 29 <!--类的属性--> 30 <property name="Age" value="16"/> 31 </object> 32 </objects> 33 </spring> 34 </configuration>
6. button对应的代码如下:
1 namespace SpringNet 2 { 3 public partial class Form1 : Form 4 { 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 private void button1_Click(object sender, EventArgs e) 11 { 12 IApplicationContext ctx = ContextRegistry.GetContext(); 13 //获取object的程序集类的对象,并且和对应的接口绑定,然后用接口接收 14 IUserInfoService lister = (IUserInfoService)ctx.GetObject("UserInfoService"); 15 MessageBox.Show(lister.msgShow()); 16 } 17 } 18 }
三. Spring.Net在MVC中应用
1:先导入dll文件。在2.0中找到这些文件,并且放置在一个新建的lib文件夹中,并且引入。
2:将案例中的Config文件夹拷贝到项目中:在webapp项目中新建一个config文件夹,用来存放xml类型的文件。
2.1 修改控制器中原本的new对象的方法。
//原本是这样new对象 ,改成下面这样,其实就时相当于改成其中一个属性,然后在配置文件中给该类中这个属性赋值
// IBLL.IUserInfoService UserInfoService = new BLL.UserInfoService();
IBLL.IUserInfoService UserInfoService { get; set; }
3:修改Config文件夹中的相关的配置信息。 该配置文件的作用主要是为类的中的一个属性赋值,注意:type中对应的是命名空间带类名的全称,程序集,我的两个就不一样然后这个bug我改了半个月.......
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net"> 3 <!--controller的程序集,专门负责相关控制器--> 4 <!--命名空间带类名的全称,程序集--> 5 <object type="OA_MVC.Controllers.UserInfoController, OA-MVC" singleton="false" > 6 <property name="UserInfoService" ref="userInfoService" /> 7 </object> 8 <object name="userInfoService" type="BLL.UserInfoService, UserInfoService" singleton="false" > 9 </object> 10 </objects>
4:修改Web.config文件中的配置。
1 <!--在<configSections>中配置以下--> 2 <sectionGroup name="spring"> 3 <!--Spring.Net配置 指对应的处理由Handler执行--> 4 <section name="context" type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc4"/> 5 </sectionGroup> 6 <!--在跳出上面这个之后,加入以下--> 7 <spring> 8 <!--Spring.Net配置 配置处理,配置xml文件路径--> 9 <context> 10 <resource uri="file://~/Config/controllers.xml"/> 11 <resource uri="file://~/Config/services.xml"/> 12 </context> 13 </spring> 14
5:可以将Config/controllers.xml文件中的配置信息分离(可以将控制器的配置与业务类的配置分离。)注意web.config文件中也要修改一下。
就是指把第三步的红色的object文件夹中的文件分离出来新建一个xml文件,并且在web.config配置中,也要注意加入业务类对应的xml文件路径。
6:修改Global文件.使其继承SpringMvcApplication
1 namespace OA_MVC 2 { 3 // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明, 4 // 请访问 http://go.microsoft.com/?LinkId=9394801 5 //SpringMvcApplication继承System.Web.HttpApplication,并且SpringMvcApplication自带容器,所以不用自己构建 6 public class MvcApplication : SpringMvcApplication //System.Web.HttpApplication 7 { 8 protected void Application_Start() 9 { 10 AreaRegistration.RegisterAllAreas(); 11 12 WebApiConfig.Register(GlobalConfiguration.Configuration); 13 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 14 RouteConfig.RegisterRoutes(RouteTable.Routes); 15 BundleConfig.RegisterBundles(BundleTable.Bundles); 16 } 17 } 18 }
四. 异常处理
1.新建一个MyExceptionAttribute类,用来处理异常,将异常加载进入队列中
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 namespace OA_MVC.Models 7 { 8 public class MyExceptionAttribute : HandleErrorAttribute 9 { 10 //新建一个异常类型的队列,并且设置静态的队列,就向同一个队列中插入 11 public static Queue<Exception> ExceptionQueue = new Queue<Exception>(); 12 public override void OnException(ExceptionContext filterContext) 13 { 14 base.OnException(filterContext); 15 Exception ex = filterContext.Exception; //创建一个异常 16 ExceptionQueue.Enqueue(ex); //将异常追加到队列最后 17 //跳转错误页 18 filterContext.HttpContext.Response.Redirect("/Error.html"); 19 } 20 } 21 }
2. 在Global.asax文件中开启线程,捕获异常,因为该文件是最初启动的,并且线程一直启动。然后将启动的线程日志放在log文件夹中。15号以后是关键代码
1 namespace OA_MVC //该文件是应用程序加载就会自动执行,并且不间断执行的 2 { 3 // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明, 4 // 请访问 http://go.microsoft.com/?LinkId=9394801 5 //SpringMvcApplication继承System.Web.HttpApplication,并且SpringMvcApplication自带容器,所以不用自己构建 6 public class MvcApplication : SpringMvcApplication //System.Web.HttpApplication 7 { 8 protected void Application_Start() 9 { 10 AreaRegistration.RegisterAllAreas(); 11 WebApiConfig.Register(GlobalConfiguration.Configuration); 12 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 13 RouteConfig.RegisterRoutes(RouteTable.Routes); 14 BundleConfig.RegisterBundles(BundleTable.Bundles); 15 //开启一个线程,扫描异常信息队列。 16 string filePath = Server.MapPath("/Log/"); //获取存放日志文件的物理路径 17 //开启一个线程池 需要传递一个委托的object 18 ThreadPool.QueueUserWorkItem((a) => 19 { 20 while (true) 21 { 22 //判断一下队列中是否有数据 23 if (MyExceptionAttribute.ExceptionQueue.Count() > 0) 24 { 25 //出队,谁先进去,谁就先出去 26 Exception ex=MyExceptionAttribute.ExceptionQueue.Dequeue();//出队 27 if (ex != null) 28 { 29 //将异常写入日志文件中。 30 string fileName = DateTime.Now.ToString("YYYY-MM-dd"); 31 //如果文件有,就追加,如果没有就新创建一个并且写入,三个参数,第一个是文件名,第二个是需要填充的内容,第三个是编码格式 32 File.AppendAllText(filePath+fileName+".txt",ex.ToString(),System.Text.Encoding.UTF8); 33 } 34 } 35 else 36 { 37 //如果队列中没有数据休息3秒钟 38 Thread.Sleep(3000); 39 } 40 } 41 }, filePath); 42 } 43 } 44 }
3. 关键点,修改App_Start文件夹下的FilterConfig文件
1 public class FilterConfig 2 { 3 public static void RegisterGlobalFilters(GlobalFilterCollection filters) 4 { 5 //捕获异常注册,修改下面代码 6 //filters.Add(new HandleErrorAttribute()); 7 filters.Add(new MyExceptionAttribute()); 8 } 9 } 10 }
五. Log4Net日志处理
Log4Net是用来记录日志的,可以将程序运行过程中的信息输出到一些地方(文件、数据库、EventLog等),日志就是程序的黑匣子,可以通过
日志查看系统的运行过程,从而发现系统的问题。日志的作用:将运行过程的步骤、成功失败记录下来,将关键性的数据记录下来分析系统问题所在。Log4J。
对于网站来讲,不能把异常信息显示给用户,异常信息只能记录到日志,出了问题把日志文件发给开发人员,就能知道问题所在。
配置Log4Net环境
(1)新建一个WebApplication 应用程序
(2)添加对log4net.dll的引用(bin\net\2.0\release 不能引用debug版本)(把相应的dll文件拷贝到项目中的lib文件夹下。)
(3)在Web.Config (或App.Config)添加配置,见备注
加入configSections配置文件中
(4)初始化:在程序最开始(Global文件中)加入log4net.Config.XmlConfigurator.Configure();不要加到页面的Load,
(5)在要打印日志的地方LogManager.GetLogger(typeof(Program)).Debug(“信息”); 。通过LogManager.GetLogger传递要记录的日志类类名获得这个类的ILog(这样在日志文件中就能看到这条日志是哪个类输出的了),然后调用Debug方法输出消息。因为一个类内部不止一个地方要打印日志,所以一般把ILog声明为一个static字段。
Private static ILog logger=LogManager.GetLogger(typeof(Test))
输出错误信息用ILog.Error方法,第二个参数可以传递Exception对象。log.Error("***错误"+ex),log.Error("***错误",ex)
测试代码:
Appender:可以将日志输出到不同的地方,不同的输出目标对应不同的Appender:RollingFileAppender(滚动文件)、AdoNetAppender(数据库)、SmtpAppender (邮件)等。
level(级别):标识这条日志信息的重要级别。None>Fatal>ERROR>WARN>DEBUG>INFO>ALL,设定一个Level,那么低于这个Level的日志是不会被写到Appender中的。
Log4Net还可以设定多个Appender,可以实现同时将日志记录到文件、数据、发送邮件等;可以设定不同的Appender的不同的Level,可以实现普通级别都记录到文件,Error以上级别发送邮件;可以实现对不同的类设定不同的Appender;还可以自定义Appender,这样可以自己实现将Error信息发短信等。
(*)除了Log4Net,还有Enterprise Library中的Logging Application Block、Apache的CommonLog 以及NLog等,都差不多。
六. 基本登录完成
1. 先加一个登陆页面,引入image文件夹,修改js和jquery文件路径。
2. 加验证码功能,先在common文件夹中加入ValidateCode.cs类文件,切记引入system.web
3. 修改登陆页面中图片src路径
七. 登录问题(重定向问题,Session问题)