最近看了一下開源專案asp.net katana,感覺公開的介面非常的簡潔優雅,channel 9 說是受到node.js的啟發設計的,katana是乙個比較老的專案,現在已經整合到asp.net core中。
從github轉殖下來的專案,這個部落格專門是從**角度去理解katana專案,所以本篇隨筆針對已經對owin有所了解的人,如果只是入門的話可以跑一下msdn的原始碼再來閱讀本篇文章。
**結構如上,簡單分析一下各個資料夾的含義,這對於理解katana專案的整體結構有乙個大的輪廓。
.build資料夾顧名思義就是編譯的資料夾,在沒使用vs的時候你可以單擊build.cmd 去編譯這個專案,十分的方便。
.nuget就是包管理工具的配置檔案,這個我們可以忽略。同理.prerelease。
development是本次的研究重點,當你開啟這個資料夾的時候你會發現乙個類庫microsoft.owin的類庫,這個是owin元件的經典實現。
functiontests是單元測試的類庫
middleware是一些中介軟體的實現,在katana已經將管道模型虛擬化成中介軟體
performance 和sandbox 是微軟的一些測試工具
security 是微軟已經寫好的驗證中介軟體,其中包括jwt和oauth的驗證方式
server 就是伺服器的實現
owin.analysis是我本人建的web程式用來debug
上面已經介紹了各個資料夾所對應的功能,相必大部分人都是一臉蒙蔽,但是不用擔心,下面就來看看具體的**,當然是從最小的例子出發。點選 getting started with owin and katan 你就能跳到msdn得到最小的例子。裡面的一系列操作就為了新增下面的乙個類和幾個reference.現在我們看一下這個類。
1using
microsoft.owin;
23 [assembly: owinstartup(typeof
(owin.analysis.startup))]
4namespace
owin.analysis5);
15}16}
17 }
usingsystem;
using
system.collections.generic;
namespace
owin
//請求的引數
object build(type returntype);//
中介軟體鏈結
建立乙個新的物件
object args);//
註冊中介軟體
}}
public在經典的實現中,引數middleware會有兩種情況,一種是delegate,一種是type,如果是type型別,則他的構造方法接受next為引數,並且裡面有乙個公開的invoke方法。如果是委託,當前委託作為引數傳遞到next中。static
if (handler == null
)
(handler);
}
object
args)
下面的**是tomiddlewarefactory的實現,在第9行和第27行分別判斷了中介軟體物件是委託型別還是type型別,由於本題例子是type物件,我們分析一下toconstructormiddlewarefactory方法。
1private
static tupleobject> tomiddlewarefactory(object middlewareobject, object
args)27
8var middlewaredelegate = middlewareobject as
delegate;
9if (middlewaredelegate != null)10
1314 tupleobject> factory =toinstancemiddlewarefactory(middlewareobject, args);
15if (factory != null)16
1920 factory =togeneratormiddlewarefactory(middlewareobject, args);
21if (factory != null)22
2526
if (middlewareobject is
type)
2730
31throw
new notsupportedexception(string
.format(cultureinfo.currentculture,
32resources.exception_middlewarenotsupported, middlewareobject.gettype().fullname));
33 }
1現在我們重點看一下這個build方法。2private
static tupleobject> toconstructormiddlewarefactory(object middlewareobject, object args, ref
delegate middlewaredelegate)314
if (!parametertypes
15 .skip(1)16
.zip(args, testargforparameter)
17 .all(x =>x))
1821
22 parameterexpression parameterexpressions = parameters.select(p =>expression.parameter(p.parametertype, p.name)).toarray();
23 newexpression callconstructor =expression.new(constructor, parameterexpressions);
24 middlewaredelegate =expression.lambda(callconstructor, parameterexpressions).compile();
25return tuple.create(parameters[0
].parametertype, middlewaredelegate, args);26}
2728
throw
new missingmethodexception(string
.format(cultureinfo.currentculture,
29 resources.exception_noconstructorfound, middlewaretype.fullname, args.length + 1
));30 }
publicbuild方法呼叫私有的buildinternal的方法。object
build(type returntype)
privateobject
buildinternal(type signature)
foreach (var middleware in
_middleware.reverse())
return
}
public這裡面有乙個概念就是integratedpipelineblueprintstage,這個是乙個鍊錶結構,每個對應的就是管道事件,每個stage都有entry point,這樣方便我們在不同的管道事件中執行中介軟體,在beginevent裡我們得到stage 的entry point,然後非同步呼叫得到結果。entry point 就是我們上例build得到的結果。void
}////
null refs for async un-buffered requests with bodies.
}
private然後我們分析一下怎麼在不同的管道中註冊事件。在msdn的文件描述的。catch
(exception ex)
}
這個api會建立乙個integratedpipelineblueprintstage,上文說這是乙個鍊錶結構,之間用next屬性連線。在不同的stage中會有entry point,然後在上面的例子中註冊到不同的管道中去呼叫。下圖是api的**。
publicstagename)
object
obj;
obj))
return
}
ConcurrentHashMap的原始碼分析
put final v putval k key,v value,boolean onlyifabsent 在上一步的else if中 f 不為null時,則判斷f的hash值是否為moved,即 1,如果為 1,表示正在擴容 else if fh f.hash moved 協助資料遷移 tab h...
DispatcherServlet的原始碼和流程分析
1 自動配置dispatcherservlet和dispatcherservletregistry 2 註冊dispatcherservlet到servletcontext 3 初始化mvc的元件 handler執行完成後,向dispatcherservlet 返回乙個modelandview物件 ...
ConcurrentHashMap底層原始碼實現
concurrenthashmap底層原始碼實現 空構造方法 常用方法put k key,v value 呼叫putval方法 key,value,false putval key,value,false 如果key或者value為空,則丟擲空指標異常,說明不能新增空值 定義hash為hash值sp...