[原创]20行ruby代码实现依赖注入框架
2015-08-01 00:34
661 查看
我需要依赖注入
业余时间开发的娱乐项目 (为了练习使用ruby语言)遵循SRP原则,业务逻辑拆分由各个service类型提供,假设存在如下几个类型
GameService 封装主要游戏业务逻辑
UserService 维护用户信息
PlayerService 封装当前玩家信息及业务逻辑
ChatService 封装聊天业务逻辑
Service之间存在依赖关系,例如
PlayerService 依赖 UserService中的方法
PlayerService 依赖 ChatService中的方法
GameService 又依赖其他三个Service中的方法
最佳解决方案,实现依赖注入
Ruby实现依赖注入 第一版 快速实现
def init_dependency_injection map = {} Kernel.send :define_method, :get_instance do |clazz| instance = map[clazz] if instance.nil? instance = clazz.new map[clazz] = instance end instance end end
init_dependency_injection方法在程序入口处调用
代码解析
初始化ioc容器
map = {}
向内核类型中添加扩展方法
get_instance(所谓的
monkey hook),
get_instance方法接受参数clazz,表示一个类型,方法中创建该类型对象并添加对象值ico容器中
PlayerService中如何使用UserService,代码如下
class PlayerService def initialize user_service = get_instance(UserService) user_service.do_sth end end
Ruby实现依赖注入 第二版 改进
我觉得使用上还可以更方便些,类似spring mvc中通过注解进行依赖注入,向Kernal中补充autowired方法def init_dependency_injection map = {} Kernel.send :define_method, :get_instance do |clazz| instance = map[clazz] if instance.nil? instance = clazz.new map[clazz] = instance end instance end Kernel.send :define_method, :autowired do |*classes| classes.each do |clazz| underscore_class_name = clazz.name.to_s.gsub(/(.)([A-Z])/, '\1_\2').downcase instance_variable_set("@#{underscore_class_name}", get_instance(clazz)) end end end
使用方式如下
class PlayerService def initialize autowired(UserService) end def x @user_service.do_sth end end
对于GameService依赖多个Services,同样简单,如下
class GameService def initialize autowired(UserService, PlayerService, ChatService) end def x @user_service.do_sth @player_service.do_sth @chat_service.do_sth end end
程序中任何类型中,都可以使用autowired方法注入所需类型对象,自动定义实例变量,便于使用
autowired方法代码解析
获取类型集合,遍历之
获取类名,由CamelCase转换为under_score,作为实例变量名
通过
instance_variable_set设置实例变量,值通过get_instance获取
perfect!
相关文章推荐
- ruby 功力修炼
- macosx zsh下安装rvm和ruby
- ruby环境sass编译中文出现Syntax error: Invalid GBK character错误解决方法
- RubySpec 重生:破蛹成蝶
- Ruby学习总结
- ruby 遍历mongo数据
- ruby 遍历mongo数据
- 嵌Ruby 2 《捆绑》
- 测试驱动开发 Ruby 命令行工具实战
- win7安装ruby on rails开发环境
- 为什么我们应该为Ruby2.0的GC感到excited!
- 关于Ruby的GC
- selinium的ruby版在windows8下安装
- Ruby 中的类和对象
- ruby中数组的常用函数
- Ruby
- 手把手教学:巧用Core Data和RubyMotion开发iOS应用
- Ruby 程序员最要好的朋友
- 安装ruby环境
- Installing MySQL Ruby Gem checking for mysql_ssl_set()... no