Dropthings研究(一):Munq一款轻量级IoC框架

Dropthings是一款完全开源的Portal网站,从网上可以下到它的源码,作者为这个网站还专门写了一本书《ASP.NET 3.5构建Web 2.0门户网站》,网站用了很多新的开发技术和很多非常好的开发技巧,对它进行研究可以说受益匪浅。它的数据库访问层用的是Linq to Sql,业务逻辑层则是把类用partial整合成了一个类,业务逻辑层只管访问数据层的接口,其它都交给了Munq。

  • 基本概念

IoC(Inversion of Control):控制反转,不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器负责将这些联系在一起。控制反转还有一个名字叫做依赖注入DI(Dependency Injection)。

  •  Munq介绍

Munq是一款轻量级而且效率高,专门为Web开发设计的IoC框架。它提供了跟Web相关的几个生命周期管理类(Web Lifetime Management),让Web应用程序去管理容器返回的类。

  •  引用Munq进行编程

使用控制反转就是为了进一步降低耦合性,接口和实现之间的关系就由一个容器来管理。

Munq提供了一个Container类,提供了Register方法Resolve方法,分别用于注册接口和相应实现类之间的关系通过接口返回实现类

通过反编译可以看到,Container类中还包含了一个至关重要的成员那就是Registration

它负责在创建接口对应的实现类的时候把实现类放在Web属性(Session,Cache,Request)里,方便下次调用,

放在哪种生命周期管理类还要看调用Registration对象的 WithLifetimeManager(ILifetimeManager manager)方法时传递的参数类型。

Munq提供了如下几个生命周期管理类(都继承自ILifetimeManager):

每个类中都提供了获取实现类的方法GetInstance,

Dropthings网站中使用的是ContainerLifetime类。

首先来看看它和AlwaysNewLifetime的区别

很明显上一个是把返回的实现类作为成员放在了注册类里面,下一个是每次获得的实现类都是新建的。

肯定有人会问了,上一个类里面在第一次返回的实现类把注册类的Instance赋值了,第二次再获取别的实现类时怎么办呢?

这就得看看注册时候的操作

 

可见每次注册的时候会新建一个注册类并把它放在一个HybridDictionary里面保存,当然取出来的时候

 Registration registration = (Registration) this.typeRegistry[new UnNamedRegistrationKey(type)];

哦~现在就清楚了!

 

HybridDictionary类:在集合较小时,使用 ListDictionary 来实现 IDictionary,然后当集合变大时,切换到 Hashtable

集合大小界定于count=10。

(扩展阅读:http://www.cnblogs.com/anders06/archive/2007/10/25/937394.html

 

再接着看生命周期管理类,可能又会有一个问题,为什么会有ASPNETRequestLifetime类和RequestLifetime类,

这两个都是关于Request的类呢?

看看它俩的GetInstance方法,就清楚了。

ASPNETRequestLifetime内部使用了HttpContext,把实现类放在它的Items里面;

RequestLifetime使用的是HttpContextBase(抽象类)。

从网上找了一段HttpContext和HttpContextBase区别

HttpContext 因为其太复杂不容易进行单元测试,在ASP.NET MVC中,各种组件均依赖于 HttpContextBase 而不是HttpContext。

HttpContextBase 类为抽象类,该类包含的成员与 HttpContext 类相同。

使用 HttpContextBase 类可以创建一些派生类,这些派生类与 HttpContext 类相似,但是可以进行自定义并在 ASP.NET 管道外部使用。

在执行单元测试时,通常使用派生类实现具有自定义行为的成员以实现正在测试的方案。

HttpContextWrapper 类是从 HttpContextBase 类派生的。 HttpContextWrapper 类用作 HttpContext 类的包装。 在运行时,通常使用 HttpContextWrapper 类的实例调用 HttpContext 对象上的成员。

所以在ASP.NET MVC编程中还是使用RequestLifetime类。

其它的几个生命周期管理类原理相同,不再赘述。

 

再来看看Container的Resolve方法

先取出注册类,再判断它的生命周期管理类是否为空,

为空就直接调用注册时传进来的方法Func<Container,object> func,把当前container作为参数传入返回实现类,

否则就调用生命周期管理类的GetInstance方法,其实内部还是去调用注册时传进来的方法Func<Container,object> func。

  • Munq亮点

Container提供了一个LazyResolve方法返回的是获得实现类的方法,

 Func<TType> LazyResolve<TType>() where TType: class
{

  return delegate {
        return (Resolve(typeof(TType)) as TType);
    };

}

据作者介绍是在不希望立刻创建实现类的情况下,例如实现类会占用一些稀缺资源,或者出于逻辑考虑使用。

 

调用实现类时

  private Dictionary<int, IDisposable> _disposableCache = new Dictionary<int, IDisposable>();

 

  private T Resolve<T>(Func<T> resolver)
            where T : IDisposable
  {
    int hashcode = typeof(T).GetHashCode();
    if (_disposableCache.ContainsKey(hashcode))
      return (T)_disposableCache[hashcode];
    else
    {
      var item = resolver();
      _disposableCache.Add(hashcode, item);
      return item;
     }
   }

就可以获得它的实现。

 

本文版权归作者和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值