This is post #10 in the Building Neno series. Please click here for a description of the Building Neno project and instructions on how to access the source code for this post.
It's Friday already -- where did the week go? Time to kick back and do something fun... like configure Spring!
... wait, wut? - me, just now
I'll configure my container first since it's pretty straight forward. Define the section, then fill the section out with a type pointing to the Spring provider I made earlier.
<configuration>
<configSections>
<section name="inversionOfControl" type="StackingCode.Moja.InversionOfControl.Configuration.InversionOfControlSection, StackingCode.Moja" />
</configSections>
<inversionOfControl>
<containerProvider type="StackingCode.Moja.InversionOfControl.Spring.ContainerProvider, StackingCode.Moja.InversionOfControl.Spring" />
</inversionOfControl>
</configuration>
Spring starts out the same way, by defining a section (or two).
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web" />
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
</configuration>
The context section is responsible for the container -- in this case I want a web context so that I have access to the request scope. (The default Spring context only has singleton and instance available.) The objects section is where I define all the objects I want in the container.
In order for Spring to give me the request scope, it needs a module defined. I'll define it twice to cover all the flavours of IIS.
<configuration>
<system.web>
<httpModules>
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web" />
</httpModules>
</system.web>
<system.webServer>
<modules>
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web" />
</modules>
<system.webServer>
</configuration>
Now I can define some of my objects. The resource element in the context section tells the context where to look for my object definitions. It's possible to specify other XML files, but I prefer to keep it all in the application's .config
file.
<configuration>
<spring>
<context>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">
<!-- Services -->
<!-- Repositories -->
<!-- Moja -->
</objects>
</spring>
</configuration>
Spring can do all sorts of automatic goodness with NHibernate and controllers. However, at this stage I'm more comfortable with just using Spring as a service locator from inside my UI. I think it's a bit clearer to the developer (me!) what is actually going on. At and below the service layer, however, automatic dependency injection everywhere.
<!-- Services -->
<object name="PostService" type="StackingCode.Neno.Services.PostService, StackingCode.Neno" scope="request">
<property name="Context" ref="Context" />
<property name="PostRepository" ref="PostRepository" />
<property name="CommentRepository" ref="CommentRepository" />
</object>
<!-- Repositories -->
<object name="CommentRepository" type="StackingCode.Neno.Repositories.NHibernate.CommentRepository, StackingCode.Neno.Repositories.NHibernate" scope="request">
<property name="Context" ref="Context" />
<property name="Session" ref="Session" />
</object>
<object name="PostRepository" type="StackingCode.Neno.Repositories.NHibernate.PostRepository, StackingCode.Neno.Repositories.NHibernate" scope="request">
<property name="Context" ref="Context" />
<property name="Session" ref="Session" />
</object>
<!-- Moja -->
<object name="Context" type="StackingCode.Moja.Repositories.NHibernate.Context, StackingCode.Moja.Repositories.NHibernate" scope="request">
<property name="Session" ref="Session" />
</object>
<object name="Session" factory-object="SessionFactory" factory-method="OpenSession" scope="request" />
<object name="SessionFactory" type="StackingCode.Moja.Repositories.NHibernate.SessionFactoryWrapper, StackingCode.Moja.Repositories.NHibernate" />
At this stage I've only defined the post service, with all of its dependencies, as an example. Everything is in the request scope except for the session factory, which is a singleton. All the NHibernate configuration takes place in the SessionFactoryWrapper
class and only needs to happen once per application.
Spring instantiates everything itself as needed, except for NHibernate sessions. I've told Spring to create those using a method on the session factory singleton instead.
I'll throw a couple of lines into HomeController
to see if it all works.
var postService = Container.Get<IPostService>();
IQueryable<Post> posts = postService.GetPosts();
foreach (Post post in posts)
Response.Write(string.Format("Title: {0}<br />Text: {1}<br />", post.Title, post.Text));
return new EmptyResult();
Running the application shows I'm missing a whole bunch of references which I'll have to add.
StackingCode.Moja.InversionOfControl.Spring
for my container.Common.Logging
for Spring.NHibernate.ByteCode.Castle
for NHibernate.NHibernate.Caches.SysCache
for NHibernate.Remotion.Data.Linq
for NHibernate.Antlr3.Runtime
for NHibernate.I also get an error.
Cannot find matching factory method 'OpenSession on Type [StackingCode.Moja.Repositories.NHibernate.SessionFactoryWrapper].
I forgot, Spring doesn't like params in methods or constructors. Remember this?
public ISession OpenSession(params IInterceptor[] interceptors)
{
var interceptorAdapter = new InterceptorAdapter(interceptors);
ISession session = SessionFactory.OpenSession(interceptorAdapter);
session.FlushMode = FlushMode.Commit;
return session;
}
I'll have to make two methods instead.
public ISession OpenSession()
{
return OpenSession(new IInterceptor[0]);
}
public ISession OpenSession(IInterceptor[] interceptors)
{
var interceptorAdapter = new InterceptorAdapter(interceptors);
ISession session = SessionFactory.OpenSession(interceptorAdapter);
session.FlushMode = FlushMode.Commit;
return session;
}
Running again, another error.
IUserService is not defined in Spring objects.
I forgot, the post service calls User.Current
. Well that's not fully implemented yet, so I'll comment the filter out for now.
Running again...
Finally, success. Neno can now talk to the database! Before I can get rid of posts.xml
, however, I need to sort a few more things out.
There are 0 comments.
Older
The Database
Older
The Database
browse with Pivot
Codility Nitrogenium Challenge
OS X Lock
HACT '13
Codility Challenges
Priority Queue
Architecture (13)
ASP.NET (2)
ASP.NET MVC (13)
Brisbane Flood (1)
Building Neno (38)
C# (4)
Challenges (3)
Collections (1)
Communicator (1)
Concurrency Control (2)
Configuration (1)
CSS (5)
DataAnnotations (2)
Database (1)
DotNetOpenAuth (2)
Entity Framework (1)
FluentNHibernate (2)
Inversion of Control (5)
JavaScript (1)
jQuery (4)
Kata (2)
Linq (7)
Markdown (4)
Mercurial (5)
NHibernate (20)
Ninject (2)
OpenID (3)
OS X (1)
Pivot (6)
PowerShell (8)
Prettify (2)
RSS (1)
Spring (3)
SQL Server (5)
T-SQL (2)
Validation (2)
Vim (1)
Visual Studio (2)
Windows Forms (3)
Windows Service (1)
Comments
Leave a Comment
Please register or login to leave a comment.