代码改变世界

AOP之PostSharp7-解决IOC 不能直接new问题,简化IOC开发和IOC对象LazyLoad

2011-12-18 21:50  破狼  阅读(2937)  评论(0编辑  收藏  举报

    经过几节的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), trueas 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(); 
    }

效果:

image

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

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

image

image 

附件下载: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