.NET:在ASPX、ASHX和MVC中使用IOC容器

来源:互联网 发布:对linux系统的认识 编辑:程序博客网 时间:2024/04/30 00:40

前言

程序开发的一个良好原则就是:“将使用和创建分开”。5年前有多少人采用这种风格呢?几乎没有。在IOC流行甚至泛滥的今天,还有一些团队没有使用IOC容器,有些是由于历史原因,有些是由于团队的文化。没有采用IOC的团队,找个机会拥抱一下吧。

我一直在用IOC容器,在此介绍一下如何将IOC集成到WebForm和WebMvc的应用系统中。

自动注入到ASPX和ASHX

框架支持

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6  7 namespace Happy.Web 8 { 9     public interface IWantAutoDependInjection10     {11     }12 }
 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6  7 namespace Happy.Web 8 { 9     [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]10     public sealed class DependToAttribute : Attribute11     {12         public Type DependToType { get; set; }13 14         public string Key { get; set; }15     }16 }
 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6  7 using System.Web; 8  9 using Microsoft.Practices.ServiceLocation;10 11 using Happy.ExtensionMethods.Reflection;12 13 namespace Happy.Web14 {15     public class DependInjectionModule : IHttpModule16     {17         public void Init(HttpApplication context)18         {19             context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;20         }21 22         private void OnPreRequestHandlerExecute(object sender, EventArgs e)23         {24             if (!(HttpContext.Current.CurrentHandler is IWantAutoDependInjection))25             {26                 return;27             }28 29             var properties = HttpContext.Current.CurrentHandler.GetType().GetProperties();30 31             foreach (var property in properties)32             {33                 var dependToAttribute = property.GetAttribute<DependToAttribute>(false);34 35                 if (dependToAttribute == null)36                 {37                     continue;38                 }39 40                 var dependType = dependToAttribute.DependToType ?? property.PropertyType;41 42                 var value = ServiceLocator.Current.GetInstance(dependType, dependToAttribute.Key ?? string.Empty);43 44                 property.SetValue(HttpContext.Current.Handler, value);45             }46         }47 48         public void Dispose()49         {50         }51     }52 }

代码示例

 1 <configuration> 2   <system.web> 3     <compilation debug="true" targetFramework="4.5" /> 4     <httpRuntime targetFramework="4.5" /> 5   </system.web> 6  7   <system.webServer> 8     <modules> 9       <add name="DependInjectionModule" type="Happy.Web.DependInjectionModule"/>10     </modules>11   </system.webServer>12 13 </configuration>
 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7  8 using Happy.Web; 9 10 namespace WebStudy11 {12     public partial class Test : System.Web.UI.Page, IWantAutoDependInjection13     {14         [DependTo]15         public ApplicationService ApplicationService { get; set; }16 17         protected void Page_Load(object sender, EventArgs e)18         {19             this.Response.Write(this.ApplicationService.GetMessage());20         }21     }22 23     public sealed class ApplicationService24     {25         public string GetMessage()26         {27             return "段光伟";28         }29     }30 }

运行结果

 

自动注入到MVC

框架支持(最新版本)

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6  7 using System.Web.Routing; 8 using System.Web.Mvc; 9 10 using Microsoft.Practices.ServiceLocation;11 12 using Happy.DesignByContract;13 14 namespace Happy.Web.Mvc15 {16     public sealed class ServiceLocationDependencyResolver : IDependencyResolver17     {18         private readonly IServiceLocator _serviceLocator;19 20         public ServiceLocationDependencyResolver(IServiceLocator serviceLocator)21         {22             Check.RequireNotNull(serviceLocator, "serviceLocator");23 24             _serviceLocator = serviceLocator;25         }26 27         public object GetService(Type serviceType)28         {29             Check.RequireNotNull(serviceType, "serviceType");30 31             try32             {33                 return _serviceLocator.GetInstance(serviceType);34             }35             catch36             {37                 return null;38             }39         }40 41         public IEnumerable<object> GetServices(Type serviceType)42         {43             Check.RequireNotNull(serviceType, "serviceType");44 45             try46             {47                 return _serviceLocator.GetAllInstances(serviceType);48             }49             catch50             {51                 return new List<object>();52             }53         }54     }55 }

代码示例

此处省略代码示例,有兴趣的朋友请留言交流。

备注

想象一下,开发人员只需要定义和声明,不需要手工组装(new)会有多爽。IOC容器的配置最好根据约定自动配置。

原创粉丝点击