我看到了 Ninject 源代码,我无法理解MvcModule(github 中的源代码)。为什么 OnePerRequestHttpModule 是通用模板类型?这意味着什么?
2 回答
As you undoubtedly know, Ninject.Web.Common
defines InRequestScope
. This scope is for the activations that should live for the lifetime of a single http request. When an http request is finished, you might want to clear your activation cache for this request, but how do you know that the request has ended?
Well, the usual way of finding out is creating an Http Module and subscribing for the EndRequest event.
Suppose you've done that. Now you need to implement the event handler. In the event handler you want to clear your activation cache for this request, but how does the handler know where this activation cache is located? Ultimately this cache is part of ninject kernel, so if only you could get access to that.
But that's no problem, right? You are the implementer, so why don't you wire up your HttpModule during your kernel set-up?
Unfortunately there are quite a few problems with this approach. First, HttpModules have to be registered during the pre application startup up phase and there is no guarantee that your kernel will be created at that time. More importantly, what if you have multiple kernels? Does each of these going to create a new instance of HTTP Module? Better to avoid that.
So this is what ninject does.
The GlobalKernelRegistration
class is almost static class that keeps per domain collection of kernels. It has one instance method - protected void MapKernels(Action<IKernel> action)
. This method executes and action on every kernel in the list. The kernel lists are kept per registration type, such as OnePerRequestHttpModule
.
So what you (as a ninject author) do is derive OnePerRequestHttpModule
from GlobalKernelRegistration
and then in your implementation of EndRequest
event handler you use this.MapKernels
to execute your code to clean up the activation cache for the request.
GlobalKernelRegistrationModule
class is a simple class that registers your generic type parameter (in your case OnePerRequestHttpModule
) and the current kernel in the registry (GlobalKernelRegistration
).
When you derive your MvcModule
from GlobalKernelRegistrationModule<OnePerRequestHttpModule>
this registration happens automatically when your MvcModule
is loaded into the kernel.
You also need to make sure that OnePerRequestHttpModule
is registered as an Http Module which is usually done in the bootstrap code inside NinjectWebCommon.cs or in NinjectHttpApplication (if the project is not using webapi).
InRequestScope
它在请求结束后停用对象。