HTML5技术

不用Unity库,自己实现.NET轻量级依赖注入 - Lizon

字号+ 作者:H5之家 来源:博客园 2015-12-02 17:41 我要评论( )

在面向对象的设计中,依赖注入(IoC)作为一种重要的设计模式,主要用于削减计算机程序的耦合问题,相对于Java中的Spring框架来说,微软企业库中的Unity框架是目前.NET平台中运用比较广泛的依赖注入框架之一(还有的Spring.NET等)。但是对于这些官方版本的

    在面向对象的设计中,依赖注入(IoC)作为一种重要的设计模式,主要用于削减计算机程序的耦合问题,相对于Java中的Spring框架来说,微软企业库中的Unity框架是目前.NET平台中运用比较广泛的依赖注入框架之一(还有的Spring.NET等)。但是对于这些“官方版本”的强大依赖注入框架,通常使用和配置都比较复杂,我个人更希望实现一种“约定胜于配置”轻量级IoC框架。

    实现依赖注入主要是运用C#中的反射技术,通过配置文件,把代码的实现注入到接口中。用户只是访问接口,对于接口的实现一概不知,可以有效地对接口和实现进行解耦,在介绍代码之前,先来看一下我们的配置文件:

    Domain.Entity.IRepository与Infrastructure.Repository都是.NET中的程序集(dll),其中Domain.Entity.IRepository中定义了领域模型中所需要的仓储接口,Infrastructure.Repository中定义了仓储接口的实现。领域模型需要访问数据的时候,并不是直接访问ADO或者ORM,而是通过访问Domain.Entity.IRepository中的仓储接口,再通过依赖注入把Infrastructure.Repository中的实现注入到接口中,这样就有效隔离了领域模型对数据实现的依赖,如果后期需要更换数据库或ORM框架,只需要实现另一个Infrastructure.Repository,并更新依赖注入配置即可。
    下面介绍轻量级依赖注入的实现方法,先贴代码:  

DependencyInjector { 根据名称和构造函数的参数加载相应的类 T GetClass<T>(string className, object[] args = null) where T : class { factoryName = typeof(T).Namespace; dllName = ConfigurationManager.AppSettings[factoryName]; fullClassName = dllName + + className; classObject = Assembly.Load(dllName).CreateInstance(fullClassName, true, BindingFlags.Default, null, args, null, null); ; return classObject as T; } }

   代码中的typeof(T).Namespace,其中T是接口的类型,获取接口的命名空间以后,再通过我们的配置文件,就可以获取类的命名空间,再加上类名,通过c#的反射机制,就可以加载类的实现。也许你会说,我们只知道接口,并不知道类名是什么,别急,我们对该代码进一步进行封装:

IoC { //通过接口名称和构造函数的参数得到实现 T Resolve<T>(object[] args = null) where T : class { className = typeof(T).Name.Substring(1); fullName = typeof(T).FullName; ); (flag != -1) { , flag); //这里去掉方法名前面的点和I className = fullName.Substring(dot + 2); } return DependencyInjector.GetClass<T>(className, args); } }

    在这里我们就用到了上面所说的”约定胜于配置“,我们约定接口的名称是在类名的前面加上I,并且接口和实现必须是独立的程序集。如果类名是Helper,那么接口的名字就必须是IHelper,我们通过去掉接口前面的I来获得实现的类名。如果是泛型接口,还需要进行特殊的处理,这里我们通过判断类型的全名中是否包含”`“符号来判断是否泛型接口。

    下面举一个使用该依赖注入的例子:

     public static Book GetById(string bookID) { IRepository<Book> bookRep = IoC.Resolve<IRepository<Book>>(); return bookRep.GetByKeys(bookID); } public int GetBookCount() { IBookRepository bookRep = IoC.Resolve<IBookRepository>(); return bookRep.GetCount(); }

    在这里我们是不知道接口的实现的,通过我们封装的IoC.Resolve方法,可以把我们配置文件中的接口实现”注入到接口“中,通过这种解耦的方式,后期我可以更加灵活地对代码进行重构。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

    JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

    2017-04-28 14:02

  • 调取百度地图接口,实现取自己的实时位置,然后可以在百度地图上添加信息标注 - QISHUANG

    调取百度地图接口,实现取自己的实时位置,然后可以在百度地图上添加

    2017-04-18 10:02

  • 妈妈再也不用担心我的移动端了:网易和淘宝的rem方案剖析 - 菜鸟先飞1992

    妈妈再也不用担心我的移动端了:网易和淘宝的rem方案剖析 - 菜鸟先飞

    2017-03-28 11:01

  • 我问我自己,你究竟想成为一个什么样的人? - Felix_ICanFixIt

    我问我自己,你究竟想成为一个什么样的人? - Felix_ICanFixIt

    2017-03-01 08:00

网友点评
t