经过几节的postsharp基础和每节的一个应用实例,已经基本PostSharp应用的能力,PostSharp主要是简化我们的开发,让编译器时候给我注入重复疲劳代码。
在今天我们的demo是,关于ioc(控制反转)的问题,ioc框架我们都会从ioc容器中取得我们的ioc对象注入,所以我们不能直接new对象得到我们的实例,必须Resolve。我一直都是很懒得人,既然有了PostSharp就的好好利用起来。大部份ioc逻辑是从以前的一篇利用Attribute简化Unity框架IOC注入转过来的,注入支持自定义配置文件,我个人不喜欢把配置信息全部写在一个web.config/app.config中,也不喜欢el的写在一个外部配置文件中,我个人倾向于每个模块在一个不能的配置文件,并在模块中在区分container容易,所以特别写了每个单独配置文件的延时加载,缓存。代码也不多,先上菜品:
- View Code
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Microsoft.Practices.Unity;
- using Microsoft.Practices.Unity.Configuration;
- using Microsoft.Practices.Unity.InterceptionExtension;
- namespace PostSharpDemo
- {
- [Serializable]
- public class IocUnityResolverAttribute : PostSharp.Aspects.LocationInterceptionAspect
- {
- private Dictionary<string, Microsoft.Practices.Unity.Configuration.UnityConfigurationSection> sectionCache = new Dictionary<string, Microsoft.Practices.Unity.Configuration.UnityConfigurationSection>();
- private static object lockObj = new object();
- public IocUnityResolverAttribute(string Container)
- {
- this.Container = Container;
- }
- public string Container
- {
- get;
- set;
- }
- public string ConfigFile
- {
- get;
- set;
- }
- public string Name
- {
- get;
- set;
- }
- public Microsoft.Practices.Unity.Configuration.UnityConfigurationSection GetUnityConfigurationSection()
- {
- if (!string.IsNullOrEmpty(this.ConfigFile))
- {
- Microsoft.Practices.Unity.Configuration.UnityConfigurationSection section = null;
- if (!sectionCache.ContainsKey(this.ConfigFile))
- {
- lock (lockObj)
- {
- if (!sectionCache.ContainsKey(this.ConfigFile))
- {
- var fileMap = new System.Configuration.ExeConfigurationFileMap { ExeConfigFilename = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, this.ConfigFile) };
- System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, System.Configuration.ConfigurationUserLevel.None);
- if (configuration == null)
- {
- throw new Exception(string.Format("Unity配置{0}不正确;", this.ConfigFile));
- }
- section = configuration.GetSection(Microsoft.Practices.Unity.Configuration.UnityConfigurationSection.SectionName) as Microsoft.Practices.Unity.Configuration.UnityConfigurationSection;
- sectionCache.Add(this.ConfigFile, section);
- }
- }
- }
- return sectionCache[this.ConfigFile];
- }
- return System.Configuration.ConfigurationManager.GetSection(Microsoft.Practices.Unity.Configuration.UnityConfigurationSection.SectionName) as Microsoft.Practices.Unity.Configuration.UnityConfigurationSection;
- }
- public override void OnGetValue(PostSharp.Aspects.LocationInterceptionArgs args)
- {
- var current = args.GetCurrentValue();
- if (current == null)
- {
- var unitySection = this.GetUnityConfigurationSection();
- if (unitySection != null)
- {
- var container = new Microsoft.Practices.Unity.UnityContainer().LoadConfiguration(unitySection, string.IsNullOrEmpty(Container) ? unitySection.Containers.Default.Name : Container);
- var obj = string.IsNullOrEmpty(Name) ? container.Resolve(args.Location.LocationType) : container.Resolve(args.Location.LocationType, Name);
- if (obj != null)
- {
- //var piabAtttr = obj.GetType().GetCustomAttributes(typeof(ELPolicyinjectionAttribute), false) as ELPolicyinjectionAttribute[];
- //if (piabAtttr.Length > 0)
- //{
- // obj = Microsoft.Practices.EnterpriseLibrary.PolicyInjection.PolicyInjection.Wrap(type, obj);
- //}
- args.Value = obj;
- args.ProceedSetValue();
- }
- }
- }
- args.ProceedGetValue();
- }
- public override bool CompileTimeValidate(PostSharp.Reflection.LocationInfo locationInfo)
- {
- var p = locationInfo.PropertyInfo;
- if (p != null)
- {
- var attrs = p.GetCustomAttributes(typeof(Microsoft.Practices.Unity.DependencyAttribute), true) as Microsoft.Practices.Unity.DependencyAttribute[];
- if (attrs != null && attrs.Length > 0)
- {
- return true;
- }
- }
- return false;
- }
- }
- }
- 复制代码
测试:
- View Code
- [IocUnityResolver("IocUnityResolver", ConfigFile = "App1.config")]
- class Program
- {
- [Microsoft.Practices.Unity.Dependency()]
- public static IIocUnityResolverAttributeTest IocUnityResolverAttributeTest
- {
- get;
- private set;
- }
- public static IIocUnityResolverAttributeTest IocUnityResolverAttributeTest2
- {
- get;
- private set;
- }
- static void Main(string[] args)
- {
- Program.IocUnityResolverAttributeTest.Test("test ioc unity!");
- Console.Read();
- }
- 复制代码
效果:
另外多加一句在AOP之PostSharp初见-OnExceptionAspect这节我们系列开篇我们看了Postsharp的多播(),所以我们可以很轻松的应用于我们的程序集,类上加Attribute实现,但是这里必须要区分Location的的注入决策,所以这里重写的基类方法的CompileTimeValidate,在有EL Unity 中Microsoft.Practices.Unity.DependencyAttribute标签的location我们才会去植入。有了这些我们就很轻松的在各个类,程序集,命名空间引用。
看看我们上边的实例反编译效果,IocUnityResolverAttributeTest带有Microsoft.Practices.Unity.DependencyAttribute标签所以会植入,而IocUnityResolverAttributeTest2没有标签所以不会植入;
附件下载:demo
- AOP之PostSharp初见-OnExceptionAspect
- AOP之PostSharp2-OnMethodBoundaryAspect
- AOP之PostSharp3-MethodInterceptionAspect
- AOP之PostSharp4-实现类INotifyPropertyChanged植入
- AOP之PostSharp5-LocationInterceptionAspect
- AOP之PostSharp6-EventInterceptionAspect
- AOP之PostSharp7-解决IOC 不能直接new问题,简化IOC开发和IOC对象LazyLoad
-
http://www.cnblogs.com/whitewolf/category/312638.html