IoC实践--ASP.NET MVC5 采用Unity依赖注入Filter详解
转载自: http://www.lanhusoft.com/Article/111.html
最近写了两篇关于ASP.NET mvc5 采用Unity依赖注入的 文章,前面两篇分别是对Controller和View,这次介绍一下:ASP.NET MVC5 采用Unity成功依赖注入Filter,对Filter的IoC稍微复杂一些。我通过对一个写日志的Filter里面的一个接口进行依赖注入,使用 了.net中的Atrribute特性技术和Filter的AOP技术,下面具体的详细步骤。
1、记日志组件接口
- namespace MVC5DependencyInjection.Abstract
- {
- public interface ILogService
- {
- void Write(string msg);
- }
- }
2、记文本文件日志组件具体类
- using MVC5DependencyInjection.Abstract;
- using System;
- using System.IO;
- namespace MVC5DependencyInjection.Concrete
- {
- public class TextLogService : ILogService
- {
- public void Write(string msg)
- {
- string logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Log\");
- if (!Directory.Exists(logDir))
- {
- Directory.CreateDirectory(logDir);
- }
- string fileName = DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
- using (StreamWriter sw = new StreamWriter(logDir + fileName, true))
- {
- sw.WriteLine(DateTime.Now.ToString() + ":" + msg);
- sw.WriteLine("---------------------------------------------------------");
- sw.Close();
- }
- }
- }
- }
这类就是负责记录信息到文本文件,日志文件放根目录的Log目录下面,一天一个文件。
3、声明一个调用日志组件的Action Filter过滤器
- using Microsoft.Practices.Unity;
- using MVC5DependencyInjection.Abstract;
- using System;
- using System.Diagnostics;
- using System.Web.Mvc;
- namespace MVC5DependencyInjection.Filters
- {
- public class LogActionFilter : FilterAttribute,IActionFilter
- {
- private ILogService logService;
- private Stopwatch timer;
- [Dependency]
- public ILogService LogService
- {
- get { return logService; }
- set { logService = value; }
- }
- //public LogActionFilter(ILogService log)
- //{
- // this.logService = log;
- //}
- public void OnActionExecuting(ActionExecutingContext filterContext)
- {
- timer = Stopwatch.StartNew();
- logService.Write(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
- + ",客户请求:"
- + filterContext.HttpContext.Request.RawUrl + ",开始");
- }
- public void OnActionExecuted(ActionExecutedContext filterContext)
- {
- timer.Stop();
- logService.Write(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
- + ",客户请求:"
- + filterContext.HttpContext.Request.RawUrl + ",结束,耗时:" + timer.Elapsed.TotalSeconds + "秒");
- }
- }
- }
这里自定义的ActionFilter过滤器主要是用一个Stopwatch监测客户 请求响应时间。这个类是继承于特性类FilterAttribute和接口IActionFilter。FilterAttribute是为了可以用特性 的形式用于某些Controller和Action。OnActionExecuting是要监测Action执行之前的方 法,OnActionExecuted是要监测Action执行之前后的方法,这两个方法的参数都是ActionExecutedContext类型,这 个参数可以获取请求相关的信息,其中就包括请求上下文HttpContext。
注意: 属性为LogService加了特性Dependency,标示可以通过Unity注入;这里是定义采用的属性的形式,而不是采用构造函数,因为这是定义是一个特性Filter,如果采用构造函数在使用的比较麻烦,要传参数。
4、应用Filter到Action
这里用我这前写的IoC实践--ASP.NET MVC5 采用Unity依赖注入View详解里面的Controller,在Show的Action方法前面加上 前面定义好的Filter,加上[LogActionFilter]。
- public class UserController : Controller
- {
- private IUser service;
- public UserController(IUser service)
- {
- this.service = service;
- }
- public ActionResult Index()
- {
- var data = this.service.GetUsers();
- return View(data);
- }
- [LogActionFilter]
- public ActionResult Show()
- {
- return View();
- }
- }
5、新加一个FilterProvider使用Unity对Filter进行依赖注入
- using Microsoft.Practices.Unity;
- using System.Collections;
- using System.Collections.Generic;
- using System.Web.Mvc;
- namespace MVC5DependencyInjection.Filters
- {
- public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider
- {
- private readonly IUnityContainer container;
- public UnityFilterAttributeFilterProvider(IUnityContainer container)
- {
- this.container = container;
- }
- protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
- {
- var attributes = base.GetControllerAttributes(controllerContext, actionDescriptor);
- this.BuildUpAttributes(attributes);
- return attributes;
- }
- protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
- {
- var attributes = base.GetActionAttributes(controllerContext, actionDescriptor);
- this.BuildUpAttributes(attributes);
- return attributes;
- }
- private void BuildUpAttributes(IEnumerable attributes)
- {
- foreach (FilterAttribute attribute in attributes)
- {
- container.BuildUp(attribute.GetType(), attribute);
- }
- }
- }
- }
我们继承FilterAttributeFilterProvider类,重写 了 GetControllerAttributes和GetActionAttributes方法。用传构造函数传入的UnityContainer对 象对指定到Action或Controller的特性进行依赖注入。
6、注册依赖使用依赖注入生效
- using Microsoft.Practices.Unity;
- using MVC5DependencyInjection.Abstract;
- using MVC5DependencyInjection.Concrete;
- using MVC5DependencyInjection.Filters;
- using System.linq;
- using System.Web.Mvc;
- using System.Web.Optimization;
- using System.Web.Routing;
- using Unity.Mvc4;
- namespace MVC5DependencyInjection
- {
- public class MvcApplication : System.Web.HttpApplication
- {
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- BundleConfig.RegisterBundles(BundleTable.Bundles);
- Initialise();
- }
- IUnityContainer BuildUnityContainer()
- {
- var container = new UnityContainer();
- container.RegisterType<IUser, SimpleUser>();
- container.RegisterInstance<IMessageService>(new MessageService
- {
- Message = "欢迎你来到wwww.lanhusoft.com",
- ImageUrl = "/Content/Images/1.jpg"
- });
- container.RegisterType<ILogService, TextLogService>();
- container.RegisterInstance<IFilterProvider>("FilterProvider", new UnityFilterAttributeFilterProvider(container));
- return container;
- }
- void Initialise()
- {
- var container = BuildUnityContainer();
- DependencyResolver.SetResolver(new UnityDependencyResolver(container));
- }
- }
- }
这行代码表示将我们自定义的UnityFilterAttributeFilterProvider绑定到内置的mvc框架里面去,使Filter能够依赖注入。
7、运行页面查看结果

8、总结
http://odetocode.com/blogs/scott/archive/2011/01/20/injectable-configurable-action-filters.aspx
转载请注明:文章转载自:蓝狐软件工作室 » IoC实践--ASP.NET MVC5 采用Unity依赖注入Filter详解
本文标题:IoC实践--ASP.NET MVC5 采用Unity依赖注入Filter详解
本文地址:http://www.lanhusoft.com/Article/111.html

浙公网安备 33010602011771号