标签:system
一.写在前面适配器模式(Adapter)
可用来在现有接口和不兼容的类之间进行适配。有助于避免大规模改写现有客户代码,其工作机制是对现有类的接口进行包装,这样客户程序就能使用这个并非为其量身打造的类而又无需为此大动手术。 ----《JS设计模式》
将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
----《Head First设计模式》
这两本书中对适配器模式定义如此,适配器模式在多种设计模式当中属于比较容易理解的一种,其目的或者说可以解决的问题是新功能/新类型,不受原有类型/方法/功能的兼容,有了适配器这种巧妙地经验,我们可以保证对修改封闭,对拓展开放。而达到此目的,正需要面向接口,并保持职责的单一性。也许对C#开发者来说,见的最多的就是SqlDataAdapter。
二.认识UseWebApi
本文所涉及OWIN,.NetFramework,Webapi 开源源码下载地址为:
ht t p s : / /g i t h u b. c o m / as p n e t/ A s p N et K a ta n a
htt p s: / / g i th u b. c o m / AS P - N E T- M V C /a s p n e tw e b s t a ck
h t t p s : / /g i t h u b . c om / d o t ne t / c or e f x
熟悉OWIN体系的小伙伴们,一定都在Startup.cs中见过也使用过app.UseWebApi吧。app是IAppBuilder的对象
Startup.cs是OWIN katana实现的启动类,刚说的UseWebApi顾名思义,就是将WebApi作为一个OWIN中间件放在整个处理流程中。app是IAppBuilder的对象,其创建由IAppBuilderFactory负责。IAppBuilder定义了三个方法,分别为Build,New和Use. 这三个方法分别负责什么呢?
Build,返回OWIN管道入口点的一个实例,由 Microsoft.Owin.Host.SystemWeb中的Init方法调用。其返回实例将被转换为AppFun类型,AppFun( using AppFunc = Func<IDictionary<string, object>, Task>;)是什么呢?它是OWIN服务器与应用程序交互的应用程序委托,我们看到这个方法在OWIN.Host中调用,应该就能大概猜到个所以然。
New,用于返回一个AppBuilder实例,由IAppBuilderFactory调用并返回。
Use,就是我们在OWIN体系中,经常使用到的方法,我们可以定义自己的OWIN中间件,按照其定义规范,并Use到处理管道中,比如用户操作日志中间件,用户身份校验中间件等。
说到这里,我们应该很清晰的了解到WebApi是OWIN的一个中间件而已了吧。举个栗子:
1 public partial class Startup 2 { 3 4 public void Configuration(IAppBuilder app) 5 { 6 // This must happen FIRST otherwise CORS will not work. 7 // 引入OWin.Cors 解决跨域访问问题 8 app.UseCors(CorsOptions.AllowAll); 9 10 GlobalConfiguration.Configure(WebApiConfig.Register);11 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);12 13 ConfigureAuth(app);14 15 app.Use<UserContextMiddleware>();16 app.Use<UserOperationMiddleware>();17 app.UseWebApi(GlobalConfiguration.Configuration);18 }19 }三.UseWebApi的实现看到这里你一定会问,为什么IAppBuilder中没有定义UseWebapi方法呢,UseWebapi的实现在System.Web.Http.Owin的WebApiAppBuilderExtensions.cs中,UseWebApi是一个C# this拓展方法,和你所想到的答案并无差。在其实现中,调用了 builder.Use(typeof(HttpMessageHandlerAdapter), options);
到这里,一定要啰嗦几句不要怪我,Adapter的实现步骤:为了使一个类或者一个功能,兼容已有类/接口,那么
1.被适配器实现目标客户的接口或抽象方法,以便参数的传入
2.所实现接口/抽象类的方法中调用目标客户的方法