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容易,所以特别写了每个单独配置文件的延时加载,缓存。代码也不多,先上菜品:
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;
}
}
}
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
作者:破 狼
出处:http://www.cnblogs.com/whitewolf/
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客、博客园--破狼和51CTO--破狼。