[原创]20行ruby代码实现依赖注入框架
我需要依赖注入
业余时间开发的娱乐项目 (为了练习使用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!
[原创]20行ruby代码实现依赖注入框架的更多相关文章
- 50行ruby代码开发一个区块链
区块链是什么?作为一个Ruby开发者,理解区块链的最好办法,就是亲自动手实现一个.只需要50行Ruby代码你就能彻底理解区块链的核心原理! 区块链 = 区块组成的链表? blockchain.ruby ...
- 只有20行Javascript代码!手把手教你写一个页面模板引擎
http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...
- 20行JS代码实现贪吃蛇
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 20行Python代码爬取王者荣耀全英雄皮肤
引言王者荣耀大家都玩过吧,没玩过的也应该听说过,作为时下最火的手机MOBA游戏,咳咳,好像跑题了.我们今天的重点是爬取王者荣耀所有英雄的所有皮肤,而且仅仅使用20行Python代码即可完成. 准备工作 ...
- Spring.NET依赖注入框架学习--入门
Spring.NET依赖注入框架学习--入门 在学些Spring.net框架之前,有必要先脑补一点知识,比如什么是依赖注入?IOC又是什么?控制反转又是什么意思?它们与Spring.net又有什么关系 ...
- [Android]依赖注入框架google的dagger
分享一下Android依赖注入框架--Google升级版Dagger2框架 Google的Dagger2是对上一版squareup的Dagger改版,话不多说直接上项目代码. Dagger2源码 Da ...
- Android Dagger依赖注入框架浅析
今天接触了Dagger这套android的依赖注入框架(DI框架).感觉跟Spring 的IOC差点儿相同吧.这个框架它的优点是它没有採用反射技术(Spring是用反射的),而是用预编译技术.因为基于 ...
- Ninject是一款.Net平台下的开源依赖注入框架
Ninject是一款.Net平台下的开源依赖注入框架.按照官方说法,它快如闪电.超级轻量,且充分利用了.Net的最新语法,使用Lambda表达式代替Xml文件完成类型绑定.Ninject结构精巧,功能 ...
- Spring.NET依赖注入框架学习--实例化容器常用方法
Spring.NET依赖注入框架学习---实例化容器常用方法 本篇学习实例化Spring.NET容器的俩种方式 1.通过XmlObjectFactory创建一个Spring.NET容器 IResour ...
随机推荐
- Activity的基本概念与Activity的生命周期
一.Activity的基本概念 Activity是Android的四大组件之一,它是一种可以包含用户界面的组件,主要用于和用户进行交互,比如打电话,照相,发送邮件,或者显示一个地图!Activity用 ...
- MySQL密码过期
1.用mysql命令行登录mysql的root用户 2.重新修改root密码 SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass'); my ...
- 旧书重温:0day2【8】狙击windows的异常处理实验
现在进入0day2的第六章内容 其中第六章的书本内容我都拍成了图片格式放在了QQ空间中(博客园一张一传,太慢了)http://user.qzone.qq.com/252738331/photo/V10 ...
- 11.求二元查找树的镜像[MirrorOfBST]
[题目] 输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点.用递归和循环两种方法完成树的镜像转换. 例如输入: 8 / \ 6 1 ...
- 【前端】HTML入门笔记
教程 HTML 指的是超文本标记语言 (Hyper Text Markup Language).使用标记标签来描述网页 HTML 提示:使用小写标签\属性\属性参考手册\HTML颜色\HTML颜色名 ...
- iOS AnchorPoint 引起的坐标问题
这里主要讨论设置AnchorPoint 改变时,会影响我们预期的布局问题: 一.初始代码布局 //参照页面 UIView *aView = [[UIView alloc]initWit ...
- win键盘映射成mac键盘
在win7系统下安装了mac虚拟机,mac的快捷键与win的键盘不一样,所以ctrl+c,ctrl+v都用不了,于是找方法映射. 搜索到 keyremap4macbook,,进到官网Karabiner ...
- js+css 实现遮罩居中弹出层(随浏览器窗口滚动条滚动)
本文为大家详细介绍下使用js实现遮罩弹出层居中,且随浏览器窗口滚动条滚动,示例代码如下,感兴趣的朋友可以参考下, js+css 实现遮罩居中弹出层(随浏览器窗口滚动条滚动) 下面看看我的原始代码: & ...
- bzoj 2159 Crash 的文明世界 && hdu 4625 JZPTREE ——第二类斯特林数+树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 学习材料:https://blog.csdn.net/litble/article/d ...
- selenium - 控制浏览器窗口的大小和浏览器最大化
1.控制浏览器大小 有些前端的页面需要查看在不同像素下的兼容情况,比如把像素设置为 480*800,然后截图看看页面显示有没有问题 WebDriver 提供了 set_windows_size() 方 ...