The Spring.NET for ASP.NET MVC Infrastructure increases your productivity when you write ASP.NET MVC 3.0 applications by making the full power of the Spring.NET framework available to your MVC projects.
Highlights of the Spring.NET for ASP.NET MVC Infrastructure for ASP.NET MVC 3.0 (also referred to in this document as Spring.Web.Mvc) are:
Spring.NET-specific Implementation of
IDependencyResolver
for Injection of
Controllers
, ActionFilters
, and
all other types requested by the ASP.NET MVC 3.0 runtime. ASP.NET
MVC 3.0 finally centralizes the previous multiple extensbility points
for Dependency Injection into a single, central responsibility: any
imlementation of the IDependencyResolver
interface.
Spring.Web.Mvc makes it extremely simple to inject dependencies of any
type into your MVC applications. Simply register your
Controllers
, ActionFilters
, etc.
with the context using any one of the typical object definition
approaches supported by Spring.NET and the Spring.Web.Mvc
infrastructure will ensure these objects are assembled correctly when
the ASP.NET MVC run-time has need of them.
Web object scopes. Just as with the Spring.NET Web Infrastructure for ASP.NET Webforms, Spring.Web.Mvc objects can be defined at the application, session, or request scope. This capability makes it easy to inject, for example, a session scoped shopping cart, into your controllers without any lower level programming.
The Spring.NET distribution ships with a Spring.Mvc3QuickStart application. This QuickStart is the best way to see how to integrate Spring.Web.Mvc into your own ASP.NET MVC applications.
Spring.Web.Mvc builds on top of the Spring.NET IoC container.
Object Definitions that make up a typical Spring.Web.Mvc-enabled
application are configured with the same standard Spring.NET XML
configuration syntax used for non web objects. To integrate with the
ASP.NET MVC runtime you need to make a few modifications to your
Web.config
file and your
Global.asax
.
The instantiation and configuration of the Spring.NET IoC
container by the Spring.Web.Mvc infrastructure is wholly transparent to
application developers, who typically never have to explicitly
instantiate and configure an IoC container manually (by, for example,
using the new
operator in C#). To effect the
transparent bootstrapping of the IoC container, you need to modify the
primary Application
class in the
Global.asax
so as to derive it from the special
SpringMvcApplication
class as shown in the following
snippet:
public class MvcApplication : SpringMvcApplication { }
Note that the SpringMvcApplication
class is
abstract so that developers may only use it indirectly as a superclass
of their own global application class in the
Global.asax
of their ASP.NET MVC applications.
After the Global.asax
is modified as indicated
above, you also need to define a root application context by adding a
Spring.NET configuration section to your Web.config
file. The final configuration file should resemble the following; your
exact configuration may vary in particulars and the following snippet
illustrates only the Spring-specfic entries and excludes the remainder
of the content (typically) required by ASP.NET MVC.
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc3"/> </sectionGroup> </configSections> <spring> <context> <resource uri="file://~/Config/Controllers.xml"/> <resource uri="file://~/Config/Filters.xml"/> <resource uri="file://~/Config/Production/Services.xml"/> <resource uri="file://~/Config/Production/Dao.xml"/> </context> </spring> </configuration>
Notes about the preceding configuration:
Define a custom configuration section handler for the
<context
>
element. If you use
Spring.NET for many applications on the same web server, it might be
easier to move the whole definition of the Spring.NET section group
to your machine.config
file.
The custom configuration section handler is of the type
Spring.Context.Support.MvcContextHandler
which in
turn instantiates an IoC container of the type
Spring.Context.Support.MvcApplicationContext
.
This ensures that all features provided by Spring.Web.Mvc, such as
request and session-scoped object definitions, are handled
properly.
Within the <spring>
element, define a root
context element. Next, specify resource locations that contain the
object definitions that are used within the web application (such as
service or business tier objects) as child elements within the
<context> element. Object definition
resources can be fully-qualified paths or URLs, or non-qualified, as
in the example above. Non-qualified resources are loaded using the
default resource type for the context, which for the
MvcApplicationContext
is the
WebResource
type.
The object definition resources do not have to be the same
resource type (for example, all file://
, all
http://
, all assembly://
, and
so on). This means that you can load some object definitions from
resources embedded directly within application assemblies
(assembly://
) while continuing to load other
object definitions from web resources that can be more easily
edited.
The default behavior, settings, ASP.NET MVC start-up related and
Spring.NET container-configuration behaviors can be modified and
controlled by overriding various methods of the
SpringMvcApplication
in your own derived instance.
The following section describes these overridable methods and their
existing behavior provided in the base
SpringMvcApplication
class. Please note that if you
choose to override any of these methods and do not subsequently invoke
the base SpringMvcApplication
class' implementation
of that same method, then you are completely responsible for ensuring
that the underlying reponsibilities of that method in the base class are
satisfied by your overloaded implementation. Without either ensuring
this or invoking the base class implementation within your overridden
method, the underlying behavior of the ASP.NET MVC integration with
Spring.NET is unlikley to function as intended.
This method is provided by the Microsoft base
HttpApplication
class and is overridden in the
SpringMvcApplication
base class to be responsible
for invoking the BuildDependencyResolver
and RegisterDependencyResolver
methods. If you choose to override the
Application_BeginRequest
implementation of the
SpringMvcApplication
class in your own
implementation, ensure that you either call
base.Application_BeginRequest
or explicitly invoke
both the BuildDependencyResolver
and RegisterDependencyResolver
methods within your override of this method.
This method is invoked by the
SpringMvcApplication
class after it has been
configured with all of its object definitions and other settings (as
detailed in Configuration of a
ASP.NET MVC Application) but immediately prior to its being
handed off to the ASP.NET MVC infrastructure for its use. Overridding
this method provides you with your last possible moment to make any
additional modifications to the IApplicationContext
before it is put into service for the ASP.NET MVC framework's use. In
the SpringMvcApplication
base class, this method is
a no-op and thus does nothing. It exists only to provide an
extensibility point for developers wishing to interact with the
IApplicationContext
at this point in the
application startup/context configuration lifecycle.
This method is responsible for assembling and returning the
Spring.NET-specific implementation of the ASP.NET MVC framework's
IDependencyResolver
interface. The provided
implementation of this method In the
SpringMvcApplication
class returns an instance of
the SpringMvcDependencyResolver
class wired up to
use the configured IApplicationContext
. For
fine-grained control of the manner in which the
IDependencyResolver
implementation is constructed,
this method may be overriddem in a class of your own derived from
SpringMvcApplication
.
This method is responsible for registering the
SpringDependencyResolver
with the ASP.NET MVC
framework, in effect telling ASP.NET MVC "please use this
SpringDependencyResolver
to create objects when
ASP.NET MVC requests them". This is the manner in which the Spring.NET
container is subsequently invoked to satisfy dependencies on
Controllers, ActionFilters
, and other object types
when they are instantiated by ASP.NET MVC in response to an Http
Request. Generally, there should be little need for the developer to
override this method, but if you do you must ensure that your either
invoke the base implementation of
RegisterDependencyResolver
from within your
implementation or that you explicitly register the
SpringMvcDependencyResolver
with the ASP.NET MVC
infrastructure yourself from witihin this method (or elsewhere at the
appropriate time).
Spring.NET web applications support an additional attribute within object definition elements that allows you to control the scope of an object:
<object id="myObject" type="MyType, MyAssembly" scope="application | session | request"/>
Possible
values for the scope attribute are application,
session, and request
. Application
scope is the default, and is used for all objects with an undefined scope
attribute. This scope creates a single instance of an object for the
duration of the IIS application, so that the objects works exactly like
the standard singleton objects in non-web applications. Session scope
defines objects so that an instance is created for each HttpSession. This
scope is ideal for objects such as user profile, shopping cart, and so on
that you want bound to a single user.
Request scope creates one instance per HTTP request. Unlike calls to
prototype objects, calls to
IApplicationContext.GetObject
return the same instance
of the request-scoped object during a single HTTP request. This allows
you, for example, to inject the same request-scoped object into multiple
pages and then use server-side transfer to move from one page to another.
As all the pages are executed within the single HTTP request in this case,
they share the same instance of the injected object.
Objects can only reference other objects that are in the same or broader scope. This means that application-scoped objects can only reference other application-scoped objects, session-scoped objects can reference both session and application-scoped objects, and request-scoped objects can reference other request-, session-, or application-scoped objects. Also, prototype objects (including all ASP.NET web pages defined within Spring.NET context) can reference singleton objects from any scope, as well as other prototype objects.