在MVC架构中,整个系统被分离为许多单独的模块(仅仅对于根据用户请求得到合适的数据这一个功能来讲,至少存在M与C的分离),而MVC设计者的初衷之一就是实现各个模块间的松耦合,即相互间的关联性更小。
先举例如下:
最简单的实现是直接创建一个EmailSender的模块,但是考虑到系统的扩展性,今后可能会改变Emial发送的方式,或者会提供更多的Emal发送的方式时,更好的方法是先创建一个IEmailSender的接口,提供一系列的方法声明:我们需要一个(或多个)这样的模块,这个(些)模块必须至少能完成接口IEmailSender中承诺的功能,然后让EmailSender实现该接口。
假如需要完成一个通过发送邮件来找回密码这样的功能模块PassWordHelp时,可以不用直接调用EmailSender,而通过调用IEmailSender里的方法来完成这一功能。如此可以实现对某个功能的调用,和该功能具体的实现进行分离,方便各个模块的扩展。如下:
代码实现如下:
public interface IEmailSender{public void SendEmial;}
public class MyEmailSender:IEmailSender{public void SendEmail(){// 实现邮件发送}}
public class PasswordResetHelper{public void ResetPassword(){IEmailSender mySender = new MyEmailSender();// 调用EmailSender 里的方法来实现邮件发送mySender.SendEmail();}}
正如上面的例子中,在
PasswordResetHelper 模块中,IEmailSender
mySender = new MyEmailSender();这句产生了依赖关系,假如今后需要发送邮件的方式不是MyEmailSender提供的方式,就必须去更改
PasswordResetHelper 模块中的代码了。很明显,
PasswordResetHelper 对EmailSender这种依赖不利于系统扩展。
对于上述问题的解决方案,就是依依赖注入(DI),或者叫做控制反转(IoC),还是先举例如下:
public class PasswordResetHelper
{
public void ResetPassword(IEmailSender mySender)
{
mySender.SendEmail();
}
}
如此,至于
PasswordResetHelper 中所需要的
IEmailSender 接口中的功能中究竟是哪个模块实现的,这与
PasswordResetHelper 无关,只需要把
IEmailSender 的某个实例传入就行了。更通行的做法是专门建一个把接口机
IEmailSender 和实现
IEmailSender 的实例MyEmailSender关联起来的容器,当需要
IEmailSender
的实例时,会自动产生MyEmailSender的实例传入
ResetPassword方法中。这样实现了把模块A对模块B的依赖抽取到模块A以外去单独管理,然后把依赖的实例传入模块A中,或许这就是"依赖注入"名称的来源吧。
public class PasswordResetHelper{private IEmailSender mySender;public PasswordResetHelper (){mySender=new SomeMethod();}}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。