标签:
刚出来工作就遇到了一个棘手的问题:依赖注入
公司的软件需求更新频率较高,所以前辈们为了满足需求,方便更新,就用到了依赖注入这个东西。
在之前都没有听说过那个东西,所以一开始简直是蒙了,然后各种百度,发现依赖注入这个东西还是个热门话题!
可是热门不代表自己能好理解,网上的好文章很多,可是自己慧根不够,看着看着就晕了。
不过文章大豆提到了一个东西 反射 。完了,又是一个没听说过的名字(博主自学开发,可能软件专业的会提到)。
于是接着各种百度 反射 ,大概了解了什么叫做 反射。可是这个时候又开始纠结反射的用法什么的(习惯性的联想思维,根本停不下来)。
总之也是比较坎坷,后来发现,至少在我这个简单的例子里,仅仅用到了反射的一句代码。
InterfaceDLL = Assembly.Load(namespacename).CreateInstance(namespacename + "." + classname);
好吧,废话了好多,看到我这篇文章的朋友可能已经看了好多关于依赖注入的文章了,可是很多文章举的例子或者说明都不好理解(可能是我自己理解能力不足,或者没有遇到自己觉得通俗易懂的文章),下面就给大家做个简单的例子:
首先,实现注入需要的材料:
1.被注入的程序(主程序,相当于写好了的应用)
2.一个接口
3.实现了 2 接口的类
这里的三个部分我们要分开编译。
第一个项目我们写一个winform程序
等下我们要拓展的或者说是变更的需求是点击“showname” 的功能。
两个输入框的name分别是 Num1,Num2
第二个项目我们写一个类库 命名为 InterfaceDLL,这个项目里只有一个接口
namespace InterfaceDLL { public interface MyInterface1 { string ShowName(string name); } }
我们先编译项目二,得到一个dll 文件,接着我们在项目一引用得到的dll
然后我们在项目一要做一下操作:
1.Form1.cs 类里边引用我们的dll的命名空间:using InterfaceDLL;//
2.然后在类里声明接口变量:MyInterface1 myinterface1;//
3.在Form1_Load事件里加上这句:myinterface1 = Assembly.Load(Num1.Text).CreateInstance(Num1.Text+ "." + Num2.Text) as MyInterface1 ;//
4.在 showname 按钮的点击事件里写上:MessageBox.Show(myinterface1.ShowName("mm"));
完成后,我们也编译项目一。
至此,项目一和项目二已经完成,接下来我们要做项目三
项目三我们也是做一个类库项目tuozhan2dll ,项目三我们也要引用项目二的dll文件
然后我们在项目三创建的类Class1 实现 MyInterface1 接口:
namespace tuozhan2dll { public class Class1:MyInterface1 { string MyInterface1.ShowName(string name) { return "your name is "+name; } } }
然后我们编译项目三。
三个项目的编译完成后,我们做一些测试前的操作:
1.将项目三产生的dll 文件放到项目一的debug 目录下,让它跟程序处于同一目录。(注意:项目三的dll不可用进行重命名)
好了,我们直接在项目一的debug 目录下运行程序(注意,我们的项目一在项目三之前就已经编译好了)
我们在左边输入框输入项目三的命名空间tuozhan2dll,在右边的输入框输入项目三中实现了项目二接口的类 Class1
然后点击 “showname” 按钮,结果如图:
注意,主程序在编译后并不知道有项目三的dll存在,它是通过 反射(可以了解一下) 创建了项目三中Class1 的实例,而Class1 实现了接口 MyInterface1 。
那我们要变更需求的时候,我么该怎么做呢?
答案是,我们只需要修改项目三实现的方法就行,当然,你也可以创建一个新的项目实现项目二的接口
比如我们把需求改成:
string MyInterface1.ShowName(string name) { return "I don‘t know who is "+name; }
然后重新编译一下 项目三,把新生成的dll 替换原来项目一debug 下的文件
结构如图:
这样就是一个完整的依赖注入例子了。
依赖注入的运用非常广泛,我现在也是刚接触一点皮毛,可能说的也不准,还望指出。
后话:之前百度的时候看到像软件的拓展插件呀就是运用注入实现的,然后自己去模拟实现了一下,以翻译应用为模型,功能拓展就是翻译功能,点击下拉框选择要翻译的目标语言,不过原理是一样的,这里其实是将拓展dll的命名空间还有类名动态的保存到配置文件,有兴趣的可以试试。这个过程看情况有时间再分享:
标签:
原文地址:http://www.cnblogs.com/mengtree/p/5558981.html