Elite Container DELPHI下的一个轻量级IoC对象容器

一、简介:

Elite Container是DELPHI下的一个轻量级IoC对象容器(IoC:Inverse of Control,反转控制)。它是参考了Java中的Spring框架(主要是配置文件的写法),并结合DELPHI的特点来构建的。相比Spring的对象容器,它提供的功能更为精简常用(如对象延迟创建、对象属性自动注入等),降低了学习的难度,并且提供了很多扩展点,你只需简单地写一个插件实现类,并在配置文件中进行简单配置,就可以让Elite Container拥有你的自定义功能!

Elite Container主要拥有以下的一些特性:
  
  1、无论使用或不使用BPL,都可以用Elite Container来构建你的程序(但不建议用纯DLL,因为各DLL中,同一个类的类型信息是不同的,不熟悉相关知识的话,有可能会带来一些问题,而这本身并不是Elite Container的问题)
  2、支持多种属性注入类型,如直接值、枚举、集合、StringList、ObjectList等。其中StringList这种注入方式,在解决键值对配置时非常有用,详细请参看相关例子
  3、支持构造函数注入。但由于Delphi的元信息不够完备,有时需要写一个构造函数调用类(写法很简单),才可让容器正确调用该类和其子类的构造函数,详细请看相关例子另外由于构造函数注入有可能会引起循环注入的问题,因此建议尽量使用属性注入来表达对象的依赖关系,不得已的时候才使用构造函数注入
  4、支持对象配置的继承。省去配置子对象时,又要把父对象的属性配置重新拷贝一遍,既麻烦又难维护。
  5、支持对象属性的自动注入。如果你的属性命名满足一定规则,便可以利用自动注入来省去大量的配置书写
  6、支持配置文件的引入,提高配置文件的可重用性
  7、支持多种对象的生命周期配置(对于无状态的管理类,如逻辑层,单例生命周期是最常用的)
  8、支持对象的别名配置
  9、增强的对象注册机制,可注册非TPersistent为基类的类(常见的如TInterfacedObject),并且容器可以区分不同单元的同名类
  10、兼容使用Delphi的RegisterClass来注册类的遗留模块
  11、大量的自定义插件扩展点。你可以自定义自己的属性注入配置方式、构造函数注入配置方式、对象配置引入方式、对象生命周期管理方式、对象属性自动注入方式等
  12、支持对象的延迟创建。以免容器初始化时,会自动实例化一些需要花费大量时间来创建,而又很少用的类。
  13、大量的可编程接口。你甚至可以自己写一个用INI、或数据库来进行配置的IoC容器!

借助Elite Container和Ioc思想,你可以更轻易地构建出具有松散耦合、重用度高的应用程序。它的核心思想就是拆分功能的接口和实现,上层只依赖于下层的接口,然后通过Elite Container的配置,把不同的实现类注入到该接口中,达到更换功能,也就是复用已有代码的目的。设计人员可以真正地发挥好自己的面向对象思想和相关设计模式,来架构企业级的应用程序,而无需象以前那样,在Delphi中用起面向对象总有点捉襟见袖的感觉。

DEMO下载地址:http://download.csdn.net/source/1891434

二、使用Elite Container的典型开发步骤:

1、新建项目,在项目选项中选择“build with runtime packages”,去掉所有的默认包,然后选择EliteContainerD7
  2、建立应用程序的领域(如对象实体、逻辑处理、接口服务等)
  3、用XML文件来配置这些对象
  4、引用elXMLConfigurateContainer单元,声明一个IelObjectContainer类型的接口变量
  5、给这个接口创建一个TelXMLConfigurateContainer的实例,把这个XML文件的路径(相对或绝对路径均可,构造函数有参数指定),作为参数传入到构造函数中
  6、TelXMLConfigurateContainer创建的时候,会自动初始化生命周期配置为"singleton",并且不是延迟创建的对象
  7、现在可以根据配置文件所配置的对象ID或别名,从容器中获取已配置好的对象或接口了
  8、调用所获取的对象或接口,来完成程序的功能

三、DEMO目录说明:

Bin 各个例子的可执行程序
  Bin\Config 各个例子所用到的配置文件
  Lib 各个例子用到的dcp文件,需要在项目设置的"Build with runtime packages"中引入
  Source 各个例子的源代码。共26个例子,用于详细介绍Elite Container的特性。请务必结合源代码、配置文件和可执行文件来理解,这样才能达到演示的目的。如果要编译例子源代码的话,请把Lib目录添加到Delphi的Library Path下,并修改下项目的输出路径。

四、DEMO简要说明:

例1:示范了容器最基本的功能。如何获取一个配置好的对象,包括以对象形式获取(GetObj),和以接口的形式获取(GetIntf)。

例2:示范了容器最基本的功能。与例1不同的是,这个例子中,类被封装了在BPL当中。这种方式是项目实际开发时,最常用的方式(以便重用业务逻辑)。注意在配置对象的时候,对象的class配置,还要加上类所在的bpl文件,然后还要在程序中对类进行注册。

例3:示范了如何把直接值(字符串、整数等)注入到属性中。这种方式常用于利用配置来改变对象的某些初始状态,例如可以把数据库链接串以这种方式注入到对象中,以便不用重新编译也能改变程序的数据库链接。

例4:示范了如何把枚举或集合注入到属性中。强大的是,配置中,你既可以写枚举的字符串名称,也可以写枚举的整数值。

例5:示范了如何把其它配置的对象注入到属性中。属性可以是对象类型,也可以是接口类型(假如被注入的对象,实现了该接口)。这是最常用的注入方式,例如把数据访问对象注入到业务逻辑对象中,以便让业务逻辑对象访问数据库。

例6:示范了如何配置一个StringList对象,并把它注入到属性中。从配置文件中可以看到,配置的方式非常多。其中KeyValueList和ObjectRefList这两个属性的配置都采用类键值对的形式,这种形式在解决映射关系时,是很常用的。

例7:示范了如何配置一个ObjectList对象,并把它注入到属性中。注意,ObjectList的OwnsObject参数是默认被设置为false的,也就是说,释放这个ObjectList,不会释放里面的对象。因为Elite Container的单例声明周期是最常用的,因此对象的生命周期应由容器来管理,不应该在ObjectList释放的时候就释放。不过也可以直接把ObjectList配置成管理生命周期,例如它里面的对象的生命周期被配置了为"prototype"的时候。你需要清楚地知道对象的生命周期是如何被管理的,才可正确使用好这种注入方式。

例8:示范了如何配置一个InterfaceList对象,并把它注入到属性中。

例9:示范了对象属性自动注入的功能。可以设置为根据属性名称("T"加上属性名来作为对象ID)、属性类型或自动模式,来尝试从容器中获取对象。自动注入会作用于没有手动配置,不是只读,类型是对象或接口的那些属性上。自动注入默认是关闭的(值为"false"),而按属性名称,是最常用的自动注入模式。

例10:示范了继承父对象的属性配置。才能够配置文件可以看到,TMyObjectB的Count、Text、Day这三个属性的值,均继承了TMyObjectA中的设置。强大的是,你还能进行属性配置的覆盖,可以看到TMyObjectB中Day的值是wdTuesday,而不是TMyObjectA中配置的wdMonday。

例11:示范了构造函数注入。注意要配置构造函数参数的类型,常见的取值有string、integer、float、boolean、string、enum、set、object、interface等。

例12:示范了对象配置的引入。通常我们可以给各个组件写独立的配置文件,然后主程序引入这几个组件的配置文件即可。这样便重用了组件的配置文件了。注意,如果对象的配置量非常巨大,可以通过设置lazy="true"来延迟载入该配置文件。

例13:示范了对象的生命周期配置。默认的三种生命周期是:单例"singleton",该对象的实例由容器来管理(不要自己释放掉它),并且每次获取都是得到同一个实例,这种生命周期是默认的生命周期;原型"prototype",容器只负责对象的创建,而不负责实例的释放,你需要自己来管理它的生命周期;线程单例"per-thread",本质也是单例模式,但是每条线程里都会有一个不同的单例。

例14:示范了对象的别名声明。此功能常用于整合资源,例如几个组件分别声明了数据库链接的对象ID,我可以通过声明别名,把这几个数据库链接的对象ID都指向同一个对象,那么就实现了几个组件用同一个数据库链接了。

例15:示范了完成注入后,让对象进行初始化处理。通常可以在这里检查对象的属性有被注入,因为写漏配置的现象有时还是难以避免的。

例16:示范了如何兼容使用RegisterClass来注册类的老模块。其实使用上是完全一样的,没任何特殊之处。

例17(进阶功能):示范了如何注入DELPHI自带的类。要注意的是,要手动对这些类进行下注册,其它就没什么特殊了。

例18(进阶功能):示范了如何获取不同单元中的同名类。配置中,class注意要加上类所在的单元名。

例19(进阶功能):示范了自定义属性注入的处理。你需要分别写一个属性值识别器和属性值注入器,然后把它在配置中进行配置即可。可以看到,例子的配置中,属性出现了自定义的类型"path"。

例20(进阶功能):示范了自定义构造函数注入的处理。你需要分别写一个构造函数参数值识别器和构造函数参数值注入器,然后把它在配置中进行配置即可。可以看到,例子的配置中,构造函数参数出现了自定义的类型"owner-selector"。

例21(进阶功能):示范了如何自定义对象配置引入机制。例子中把对象的配置封装在了DLL中,对配置起到了简单的保护作用。因为Delphi被大量使用在客户端程序中,这跟Java是有区别的。因此这可以说是具有Delphi特色的一个很有用的扩展点。

例22(进阶功能):示范了自定义对象的生命周期管理方式。

例23(进阶功能):示范了自定义的对象属性自动注入器的编写。

例24(进阶功能):示范了如何写构造函数调用器。当出现以下两种情况时,你才需要为类写一个构造函数调用器:基类的构造函数不是虚函数,而你在子类中又声明了该构造函数;基类的构造函数虽然是虚函数,但是在子类中,你对它进行了重新声明,或者提供了重载的版本。一般调用器的逻辑,需要检查参数的个数、签名,根据重载的版本,判断参数是否存在,参数类型是否正确等。

例25(进阶功能):示范了对象属性的延迟获取。例子中获取TExample时,三个属性均是没值的,只有在它们被访问到的时候,才用容器中获取所配置的对象。这样便大大增加了TExample的获取速度(这三个属性所配置的类,为了演示需要,在创建时都人工sleep了一段时间作为延迟)

例26(进阶功能):示范了如何注册不是TPersistent作为基类的类。

五、其它说明:

Elite Container可支持Delphi 7以上的任何版本,目前暂只提供D7的版本供试用。另外放出此DEMO,主要的目的是为了能及时收集大家的反馈意见而已,容器本身不可以避免尚会存在一些问题,如内存泄露、缺乏线程保护等,暂时请勿用于实际项目中,否则后果自负。

时间: 2025-01-07 07:08:31

Elite Container DELPHI下的一个轻量级IoC对象容器的相关文章

C# 对轻量级(IoC Container)依赖注入Unity的使用

概述 Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.Unity可以处理那些从事基于组件的软件工程的开发人员所面对的问题.构建一个成功应用程序的关键是实现非常松散的耦合设计.松散耦合的应用程序更灵活,更易于维护.这样的程序也更容易在开发期间进行测试.你可以模拟对象,具有较强的具体依赖关系的垫片(轻量级模拟实现),如数据库连接,网络连接,ERP连接,和丰富的用户界面组件.例如,处理客户信息的对象可能依赖于其他对象访问的数据存储,验证信息,并检查该用户是否被授权执行更

**IOS:xib文件解析(xib和storyboard的比较,一个轻量级一个重量级)

使用Xcode做iOS项目,经常会和Xib文件打交道,因为Xib文件直观的展现出运行时视图的外观,所以上手非常容易,使用也很方便,但对于从未用纯代码写过视图的童鞋,多数对Xib的理解有些片面. Xib文件是什么? A nib file describes the visual elements of your application’s user interface, including windows, views, controls, and many others. It can also

DELPHI下的SOCK编程

本文是写给公司新来的程序员的,算是一点培训的教材.本文不会涉及太多的编程细节,只是简单讲解在DELPHI下进行Winsock编程最好了解的知识. 题外话:我认为学习编程就如同学习外语一样,最好的方式是你先学会如何去运用它,然后才是了解它的语言特性.语法之类的东西.不过很可惜,我们以前的外语教育使用了相反的过程.软件编程也是一样,在很多人的大学阶段,你更多的是学习那些理论知识,学习“语法”,这里,我丝毫没有贬低理论知识重要性的意思.理论知识和实践是相辅相成的,但一个恰当的学习方式,很多时候可以让学

DELPHI下API简述(1800个API)

DELPHI下API简述 http://zero.cnbct.org/show.asp?id=144 auxGetDevCaps API 获取附属设备容量 auxGetNumDevs API 返回附属设备数量 auxGetVolume API 获取当前卷设置 auxOutMessage API 向输出设备发送消息 auxSetVolume API 设置附属设备卷 AbortDoc API 终止一项打印作业 AbortPath API 终止或取消DC中的一切路径 AbortPrinter API

Delphi下将自己写的Form加入到对象库

1.设计好窗体,在窗体空白的地方点击右键,在弹出的菜单中选中“Add to Respository”.在弹出的对话框中填写标题.描述.作者等信息,选择存放的页.完成后点“OK”保存. 2.打开Tools->Repository,选中相应的页,可以修改已加入对象(窗体)的属性或删除已加入的对象. 相关资料:对象库(Object Respository)(1)Delphi提供了一种可以在工程之间共享对象的功能,对象库(ObjectRespository)就是负责 这项功能的机制.你可以将开发完成的窗

Delphi下的RTTI函数大全

http://ljz9425.blog.163.com/blog/static/369148572008111635253858/ Delphi下的RTTI(下) 2008-12-16 15:52:53|  分类: Delphi |字号 订阅目 录===============================================================================⊙ GetTypeData 函数⊙ GetPropInfo 函数⊙ FindPropInfo

Delphi下IOCP开源框架:DIOCP 成功应用案例分享

首先说明,该项目不是本人的项目,本文转自盒子. 该项目使用的DIOCP版本为1.0,目前diocp为3.5 以下是盒子的原文 ------------------------------------------------------------------------------ DIOCP是Delphi下进行IOCP服务端通讯开发的一个非常好的开源框架,稳定.高效并且使用起来十分简单.     自己两个多月之前因为需要使用Delphi开发一个TCP服务端,当时也是到处爬文,希望找到一个稳定且

Delphi下利用WinIo模拟鼠标键盘详解

http://www.cnblogs.com/rogee/archive/2010/09/14/1827248.html 本文最早在编程论坛上发表,文章地址:http://programbbs.com/bbs/view12-17207-1.htm,相关文件可以在上述地址的页面中下载.转载时请注明出处. 前言 一日发现SendInput对某程序居然无效,无奈只好开始研究WinIo.上网查了很多资料,发现关于WinIo模拟鼠标键盘的资料很少,有的也只是支言片语讲的不是很详细,而且大部分都是关于模拟键

一个轻量级分布式RPC框架--NettyRpc

1.背景 最近在搜索Netty和Zookeeper方面的文章时,看到了这篇文章<轻量级分布式 RPC 框架>,作者用Zookeeper.Netty和Spring写了一个轻量级的分布式RPC框架.花了一些时间看了下他的代码,写的干净简单,写的RPC框架可以算是一个简易版的dubbo.这个RPC框架虽小,但是麻雀虽小,五脏俱全,有兴趣的可以学习一下. 项目地址:https://github.com/luxiaoxun/NettyRpc 自己花了点时间整理了下代码,并修改一些问题,以下是自己学习的一