经过几节的postsharp基础和每节的一个应用实例,已经基本PostSharp应用的能力,PostSharp主要是简化我们的开发,让编译器时候给我注入重复疲劳代码。  

   在今天我们的demo是,关于ioc(控制反转)的问题,ioc框架我们都会从ioc容器中取得我们的ioc对象注入,所以我们不能直接new对象得到我们的实例,必须Resolve。我一直都是很懒得人,既然有了PostSharp就的好好利用起来。大部份ioc逻辑是从以前的一篇利用Attribute简化Unity框架IOC注入转过来的,注入支持自定义配置文件,我个人不喜欢把配置信息全部写在一个web.config/app.config中,也不喜欢el的写在一个外部配置文件中,我个人倾向于每个模块在一个不能的配置文件,并在模块中在区分container容易,所以特别写了每个单独配置文件的延时加载,缓存。代码也不多,先上菜品:

  1. View Code   
  2.  
  3. using System;   
  4. using System.Collections.Generic;   
  5. using System.Linq;   
  6. using System.Text;   
  7. using Microsoft.Practices.Unity;   
  8. using Microsoft.Practices.Unity.Configuration;   
  9. using Microsoft.Practices.Unity.InterceptionExtension;   
  10.  
  11. namespace PostSharpDemo   
  12. {   
  13.     [Serializable]   
  14.     public class IocUnityResolverAttribute : PostSharp.Aspects.LocationInterceptionAspect   
  15.     {   
  16.         private Dictionary<string, Microsoft.Practices.Unity.Configuration.UnityConfigurationSection> sectionCache = new Dictionary<string, Microsoft.Practices.Unity.Configuration.UnityConfigurationSection>();   
  17.         private static object lockObj = new object();   
  18.         public IocUnityResolverAttribute(string Container)   
  19.         {   
  20.             this.Container = Container;   
  21.         }   
  22.  
  23.         public string Container   
  24.         {   
  25.             get;   
  26.             set;   
  27.         }   
  28.  
  29.         public string ConfigFile   
  30.         {   
  31.             get;   
  32.             set;   
  33.         }   
  34.  
  35.         public string Name   
  36.         {   
  37.             get;   
  38.             set;   
  39.         }   
  40.  
  41.         public Microsoft.Practices.Unity.Configuration.UnityConfigurationSection GetUnityConfigurationSection()   
  42.         {   
  43.             if (!string.IsNullOrEmpty(this.ConfigFile))   
  44.             {   
  45.                 Microsoft.Practices.Unity.Configuration.UnityConfigurationSection section = null;   
  46.                 if (!sectionCache.ContainsKey(this.ConfigFile))   
  47.                 {   
  48.                     lock (lockObj)   
  49.                     {   
  50.                         if (!sectionCache.ContainsKey(this.ConfigFile))   
  51.                         {   
  52.                             var fileMap = new System.Configuration.ExeConfigurationFileMap { ExeConfigFilename = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, this.ConfigFile) };   
  53.                             System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, System.Configuration.ConfigurationUserLevel.None);   
  54.                             if (configuration == null)   
  55.                             {   
  56.                                 throw new Exception(string.Format("Unity配置{0}不正确;", this.ConfigFile));   
  57.                             }   
  58.                             section = configuration.GetSection(Microsoft.Practices.Unity.Configuration.UnityConfigurationSection.SectionName) as Microsoft.Practices.Unity.Configuration.UnityConfigurationSection;   
  59.                             sectionCache.Add(this.ConfigFile, section);   
  60.                         }   
  61.                     }   
  62.                 }   
  63.                 return sectionCache[this.ConfigFile];   
  64.             }   
  65.  
  66.             return System.Configuration.ConfigurationManager.GetSection(Microsoft.Practices.Unity.Configuration.UnityConfigurationSection.SectionName) as Microsoft.Practices.Unity.Configuration.UnityConfigurationSection;   
  67.         }   
  68.  
  69.         public override void OnGetValue(PostSharp.Aspects.LocationInterceptionArgs args)   
  70.         {   
  71.             var current = args.GetCurrentValue();   
  72.             if (current == null)   
  73.             {   
  74.                 var unitySection = this.GetUnityConfigurationSection();   
  75.                 if (unitySection != null)   
  76.                 {   
  77.                     var container = new Microsoft.Practices.Unity.UnityContainer().LoadConfiguration(unitySection, string.IsNullOrEmpty(Container) ? unitySection.Containers.Default.Name : Container);   
  78.                     var obj = string.IsNullOrEmpty(Name) ? container.Resolve(args.Location.LocationType) : container.Resolve(args.Location.LocationType, Name);   
  79.                     if (obj != null)   
  80.                     {   
  81.                         //var piabAtttr = obj.GetType().GetCustomAttributes(typeof(ELPolicyinjectionAttribute), falseas ELPolicyinjectionAttribute[];   
  82.                         //if (piabAtttr.Length > 0)   
  83.                         //{   
  84.                         //    obj = Microsoft.Practices.EnterpriseLibrary.PolicyInjection.PolicyInjection.Wrap(type, obj);   
  85.                         //}   
  86.                         args.Value = obj;   
  87.                         args.ProceedSetValue();   
  88.                     }   
  89.                 }   
  90.             }   
  91.             args.ProceedGetValue();   
  92.         }   
  93.  
  94.         public override bool CompileTimeValidate(PostSharp.Reflection.LocationInfo locationInfo)   
  95.         {   
  96.             var p = locationInfo.PropertyInfo;             
  97.             if (p != null)   
  98.             {                 
  99.                 var attrs = p.GetCustomAttributes(typeof(Microsoft.Practices.Unity.DependencyAttribute), trueas Microsoft.Practices.Unity.DependencyAttribute[];   
  100.                 if (attrs != null && attrs.Length > 0)   
  101.                 {   
  102.                     return true;   
  103.                 }   
  104.             }   
  105.             return false;   
  106.         }   
  107.     }   
  108. }  
  109. 复制代码 

测试:

  1. View Code   
  2.  
  3. [IocUnityResolver("IocUnityResolver", ConfigFile = "App1.config")]   
  4.    class Program   
  5.    {   
  6.        [Microsoft.Practices.Unity.Dependency()]          
  7.        public static IIocUnityResolverAttributeTest IocUnityResolverAttributeTest   
  8.        {   
  9.            get;   
  10.            private set;   
  11.  
  12.        }   
  13.        public static IIocUnityResolverAttributeTest IocUnityResolverAttributeTest2   
  14.        {   
  15.            get;   
  16.            private set;   
  17.  
  18.        }   
  19.  
  20.        static void Main(string[] args)   
  21.        {   
  22.  
  23. Program.IocUnityResolverAttributeTest.Test("test ioc unity!");   
  24.  
  25.         Console.Read();   
  26.     }  
  27. 复制代码 

效果:

另外多加一句在AOP之PostSharp初见-OnExceptionAspect这节我们系列开篇我们看了Postsharp的多播(),所以我们可以很轻松的应用于我们的程序集,类上加Attribute实现,但是这里必须要区分Location的的注入决策,所以这里重写的基类方法的CompileTimeValidate,在有EL Unity 中Microsoft.Practices.Unity.DependencyAttribute标签的location我们才会去植入。有了这些我们就很轻松的在各个类,程序集,命名空间引用。

看看我们上边的实例反编译效果,IocUnityResolverAttributeTest带有Microsoft.Practices.Unity.DependencyAttribute标签所以会植入,而IocUnityResolverAttributeTest2没有标签所以不会植入;

 

附件下载:demo