我需要依赖注入

业余时间开发的娱乐项目 (为了练习使用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方法代码解析

  1. 获取类型集合,遍历之
  2. 获取类名,由CamelCase转换为under_score,作为实例变量名
  3. 通过instance_variable_set设置实例变量,值通过get_instance获取

perfect!

[原创]20行ruby代码实现依赖注入框架的更多相关文章

  1. 50行ruby代码开发一个区块链

    区块链是什么?作为一个Ruby开发者,理解区块链的最好办法,就是亲自动手实现一个.只需要50行Ruby代码你就能彻底理解区块链的核心原理! 区块链 = 区块组成的链表? blockchain.ruby ...

  2. 只有20行Javascript代码!手把手教你写一个页面模板引擎

    http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...

  3. 20行JS代码实现贪吃蛇

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 20行Python代码爬取王者荣耀全英雄皮肤

    引言王者荣耀大家都玩过吧,没玩过的也应该听说过,作为时下最火的手机MOBA游戏,咳咳,好像跑题了.我们今天的重点是爬取王者荣耀所有英雄的所有皮肤,而且仅仅使用20行Python代码即可完成. 准备工作 ...

  5. Spring.NET依赖注入框架学习--入门

    Spring.NET依赖注入框架学习--入门 在学些Spring.net框架之前,有必要先脑补一点知识,比如什么是依赖注入?IOC又是什么?控制反转又是什么意思?它们与Spring.net又有什么关系 ...

  6. [Android]依赖注入框架google的dagger

    分享一下Android依赖注入框架--Google升级版Dagger2框架 Google的Dagger2是对上一版squareup的Dagger改版,话不多说直接上项目代码. Dagger2源码 Da ...

  7. Android Dagger依赖注入框架浅析

    今天接触了Dagger这套android的依赖注入框架(DI框架).感觉跟Spring 的IOC差点儿相同吧.这个框架它的优点是它没有採用反射技术(Spring是用反射的),而是用预编译技术.因为基于 ...

  8. Ninject是一款.Net平台下的开源依赖注入框架

    Ninject是一款.Net平台下的开源依赖注入框架.按照官方说法,它快如闪电.超级轻量,且充分利用了.Net的最新语法,使用Lambda表达式代替Xml文件完成类型绑定.Ninject结构精巧,功能 ...

  9. Spring.NET依赖注入框架学习--实例化容器常用方法

    Spring.NET依赖注入框架学习---实例化容器常用方法 本篇学习实例化Spring.NET容器的俩种方式 1.通过XmlObjectFactory创建一个Spring.NET容器 IResour ...

随机推荐

  1. 【51nod-1046】最大子矩阵和

    一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值.   例如:3*3的矩阵:   -1 3 -1 2 -1 3 -3 1 2   和最大的子矩阵是:   3 ...

  2. tomcat映射物理路径

    <Context path="/woyoubaoweb/upload" docBase="/opt/file/image/woyoubaoweb/upload&qu ...

  3. LeetCode OJ:Valid Anagram(有效字谜问题)

    Given two strings s and t, write a function to determine if t is an anagram of s. For example,s = &q ...

  4. UI-不常用控件 UIActivityIndicatorView、UIProgressView、UISegmentedControl、UIStepper、UISwitch、UITextView、UIAlertController

    1 //UIActivityIndicatorView //小菊花,加载================================================================ ...

  5. React 源码剖析系列 - 生命周期的管理艺术

    目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ...

  6. linux时间管理 之 jiffies

    1.jiffies 又称时钟滴答,是一个全局变量,它的值在系统引导的时候初始化为0,在时钟中断初始化完成后,每次时钟中断发生,在时钟中断处理例程中都会将jiffies的值 +1. jiffies_64 ...

  7. tf随笔-5

    # -*- coding: utf-8 -*-import tensorflow as tfw1=tf.Variable(tf.random_normal([2,6],stddev=1))w2=tf. ...

  8. hdu-5117 Fluorescent(状压dp)

    题目链接: Fluorescent Time Limit: 3000/3000 MS (Java/Others)     Memory Limit: 512000/512000 K (Java/Oth ...

  9. js 扩展实例

    //扩展实例1 字符串中首字符转大写 var test=' this is '; String.prototype.mytrim=function(){ var re=/^\s+(.*?)\s+$/; ...

  10. Linux使用lrzsz上传下载文件

    1.当然是要安装lrzsz这个程序 yum -y install lrzsz 2.该程序的使用 //下载文件 sz filepath.ext//文件会默认下载到系统的Downloads目录 //上传文 ...