ASP.NET Core依赖注入系列教程之控制反转(IoC)(3)

public class MvcEngine { public void Start(Uri address) { while (true) { Request request = this.OnListenAndReceiveRequest(address); Task.Run(() => { Controller controller = this.OnActivateController(request); View view = this.OnExecuteContrller(controller); this.OnRenderView(view); }); } } protected virtual Request OnListenAndReceiveRequest(Uri address) ; protected virtual Controller OnActivateController(Request request) ; protected virtual View OnExecuteContrller(Controller controller) ; protected virtual void OnRenderView(View view) ; }

对于具体的应用来说,如果定义在MvcEngine针对请求的处理方式完全符合它的要求,它只需要创建这个一个MvcEngine对象,然后指定一个对应的基地址调用模板方法Start开启这个MVC引擎即可。如果该MVC引擎处理请求的某个环节不能满足它的要求,它可以创建MvcEngine的派生类,并重写实现该环节的相应虚方法即可。比如说定义在某个应用程序中的Controller都是无状态的,它希望采用单例(Singleton)的方式重用已经激活的Controller以提高性能,那么它就可以按照如下的方式创建一个自定义的FoobarMvcEngine并按照自己的方式重写OnActivateController方法既可。

public class FoobarMvcEngine : MvcEngine { protected override View OnExecuteContrller(Controller controller) { <<省略实现>> } }

模板方法如果结合“事件注册”往往可以使应用程序对流程的定制变得更加自由。如下面的代码片段所示,我们为Controller的激活与执行以及View的呈现定义了六个事件,它们分别在这个三个环节开始之前和结束之后被触发。这么一个MvcEngine可以直接被使用,应用程序只需要注册相应的事件完成对请求处理流程的定制。

public class MvcEngine { //其他成员 protected virtual Controller OnActivateController(Request request) ; protected virtual View OnExecuteContrller(Controller controller) ; protected virtual void OnRenderView(View view) ; public EventHandler<ControllerActivationEventArgs> ControllerActivating; public EventHandler<ControllerActivationEventArgs> ControllerActivated; public EventHandler<ControllerExecutionEventArgs> ControllerExecuting; public EventHandler<ControllerExecutionEventArgs> ControllerExecuted; public EventHandler<ViewRenderEventArgs> ViewRendering; public EventHandler<ViewRenderEventArgs> ViewRendered; }

工厂方法(Factory Method)

对于一个复杂的流程来说,我们倾向于将组成该流程的各个环节实现在相应独立的组件之中,那么针对流程的定制就可以通过提供不同组件的形式来实现。我们知道23种设计模式之中有一种重要的类型,那就是“创建型模式”,比如常用的“工厂方法”和“抽象工厂”,那么IoC所体现的针对流程的共享与定制可以通过它们来完成。

ASP.NET Core依赖注入系列教程之控制反转(IoC)

所谓的工厂方法,说白了就是在某个类中用于提供依赖对象的方法,这个方法可以是一个单纯的虚方法,也可以是具有默认实现的虚方法,至于方法声明的返回类型,可以是一个接口或者抽象类,也可以是未被封闭(Sealed)的具体类型。作为它的派生类型,它可以实现或者重写工厂方法以提供所需的具体对象。

同样以我们的MVC框架为例,我们让独立的对象来完成组成整个请求处理流程的四个核心环节。具体来说,我们分别定义了四个核心的类型(Listener、ControllerActivator、ControllerExecutor和ViewGenderer)来分别负责请求监听与接收、Controller的激活、Controller的执行以及View的呈现。这四个对象按照如右图所示的顺序相互协作完成对请求的处理。

如下所示的Listener、ControllerActivator、ControllerExecutor和ViewGenderer这四个类型的简单定义。我们没有将它们定义成单纯的抽象类或者接口,而是未被封闭可以被继承的一般类型,定义其中的虚方法具有默认的实现。只有这些默认的实现方式无法满足应用程序具体需求的时候,我们才需要定义相应的派生类。

public class Listener { public virtual Request Listen(Uri address) ; } public class ControllerActivator { public virtual Controller ActivateController(Request request) ; } public class ControllerExecutor { public virtual View ExecuteController(Controller controller) ; } public class ViewRenderer { public virtual void RenderView(View view) ; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdsjsx.html