在.Net 4.0下用dynamic为你的系统解耦

.Net的应用程序为了能够使用已有的组件或者类库,在.net 4.0以前唯一的方法就是去引用这个组件所在DLL,或者是引用该组件的声明接口(Interface)的DLL然后做通过Activator或者是反射去构造该组件。无论如何你都要在你使用该组件Project里面做一个DLL的引用。虽然引用组件声明接口的方法其实已经是耦合度不算高了,能够把定义和实现分离了。但是很不幸的是好像微软的开发人员都不喜欢将Interface单独放置到一个DLL里面,一般都是有Interface然后就会在同一个DLL里面带了个默认的实现(据说JAVA的好多实现都做到了Interface和实现没有放置到同一个jar里面的)。使得引用DLL一般比较大,在一般情况下,如果你的程序不考虑升级,不是通用类库考虑让别人经常调用的话,这种做法是没什么问题的。但是如果你提供的是一个通用的类库而且你又使用了另外一个通用类库(通常在企业里面开发自己的开发框架都会有这种情况,在自己的开发框架里面直接应用微软的企业库Enterprise Library)。在项目组想用你的框架的时候,发现微软的企业库已经升级了,他们想用最新的企业库,而你的的框架又没来得及升级的时候那就会变得很痛苦了,特别是使用的强名的。动不动就给你搞一个引用不匹配的错误出来。
新的C#出来了,dynamic这个关键字让我们看到了动态语言的特性了,于是就考虑着要不要用它来试试为我们的系统做一个解耦呢?于是做了个Sample,尝试在一个没有引用Unity的类库里面直接试用Unity。
image
Project没有引用任何跟Unity相关的东西,但是我们在代码里面
Code public class DyActive { const string Con_ContainerName = "Container"; public static Dictionarystring, object Session { get; set; } public static void ActiveByDynamic(int times) { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i times; i++) { dynamic container = Session[Con_ContainerName]; ISubscriberRepositoryobject, object repository = container.ResolveISubscriberRepositoryobject, object(); try { Subscriber p = new Subscriber() { EmailAddress = "abce@g.cn" }; repository.Add(p); } catch (ArgumentNullException ex) { Console.WriteLine(string.Format("Parameter {0} is null.", ex.ParamName)); } } watch.Stop(); Console.WriteLine("Active By Dynamic! Elapsed:阰{0}", watch.ElapsedMilliseconds); } } 当然我们不会在这里构造Unity的Container的。

代码写好了,编译也没问题,那要在主程序里面调用看看能不能用了。
Main static void Main(string[] args) { IUnityContainer container = new UnityContainer(); var section = (UnityConfigurationSection)System.Configuration.ConfigurationManager.GetSection("unity"); section.Containers[0].Configure(container); Session["Container"] = container; DyActive.Session = Session; System.Console.WriteLine("Times:{0}", times); DyActive.ActiveByDynamic(times); ActiveByInterface(); times = 10000; System.Console.WriteLine("Times:{0}", times); DyActive.ActiveByDynamic(times); ActiveByInterface(); times = 1000; System.Console.WriteLine("Times:{0}", times); DyActive.ActiveByDynamic(times); ActiveByInterface(); times = 100; System.Console.WriteLine("Times:{0}", times); DyActive.ActiveByDynamic(times); ActiveByInterface(); System.Console.WriteLine("Press 'Enter' to exit!"); System.Console.ReadLine(); }







使用这个类库的时候就跟普通调用没区别了。当然我们需要在Main里面构造好了Container然后再传进去。
程序跑起来了,似乎一点问题都没有,但是dynamic肯定会给系统带来点损失的吧,如果这样轻松解耦,而又不损失点什么的话那岂不是鱼与熊掌可以兼得?第一时间肯定猜是性能有损失,但是具体损失多少呢?大家看看下面的结果
image
想不到吧,居然只是在第一次使用的时候慢了点(其实.net程序都这样的)。其他时候Interface调用不相上下。
这应该是个比较满意的结果了。看来微软在IronPython上面的积累一点都没白费啊!
Sample Code如果有兴趣的话,可以短消息找我要。









posted @ 2013-01-14 14:09  gnhao  阅读(285)  评论(0编辑  收藏  举报