Showing posts with label mvc3. Show all posts
Showing posts with label mvc3. Show all posts

Friday, October 28, 2011

Enabling Dependency Injection In Web Forms Pages and User Controls using Spring.NET

In one of the previous post, I mentioned, How MVC3 and Web Forms can exist side by side in one project.  We also saw, how we could Enable Dependency Injection using Spring.NET in an MVC3 Application.

But, What about the old Web Form pages and user controls?  Can we Enable Dependency Injection in them, so that we can create loosely coupled code?

Surely there is a way of doing this using Spring.NET.  In this post we will carry on from where we left and we will try to enable Dependency Injection even for Web Pages and User Controls.  Before moving any further, if you have not already seen my previous post of integrating Spring.NET with MVC3 Application, now is a good time to see it.

Without wasting any more time, let's see how we can enable Dependency Injection in Web Forms and User Controls using Spring.NET

How Do they Do it?

For sake of this post, let's say we have a web page called Default.aspx under the Pages directory.  The structure of the project looks somewhat like this

The project structure with Default.aspx
Our task is to inject the AccountService into the Default.aspx page.  As mentioned in the previous post AccountService is a class that was already configured in Spring.NET, it has one method UserCount and we are going to show the user count on the Default.aspx page.

The steps to enabled dependency injection in web-forms web pages using Spring.NET are as follows:
  • Add HttpHandler, called Spring.Web.Support.PageHandlerFactory for path *.aspx
  • Make code changes to Default.aspx to fetch the UserCount from AccountService
  • Configure the dependencies of Default.aspx in web.xml (web.xml is a spring config file which we created in the previous post)
Let look at each step in more detail.

Step - 1 - Add HttpHandler Spring.Web.Support.PageHandlerFactory for path *.aspx

This step is pretty straight forward all we need to do is, Add an HttpHandler, called Spring.Web.Support.PageHandlerFactory.  We need to configure it against the path *.aspx.  This is required so that, Spring.NET gets an opportunity to perform Dependency Injection when a request comes for any web-forms web page. 

We need to add the handler to the <httpHandlers> tag in the web.config.  Updated web.config looks like

Step - 2 - Make code changes to Default.aspx to fetch the UserCount from AccountService

Lets look at the Default.aspx page
As you can see the html code of Default.aspx is very simple. It just has a label called userCount which will hold the value of number of users in the system.

We will get the value of userCount from AccoutService. Let's look at the code of Default.aspx.cs file The code of Default.aspx.cs has no surprises, it has a property AccoutService. We will plan to injet an implementation of AccoutService using Spring.NET.  In the Page_Load method, we simply set the userCount label with the value returned by the UserCount method of AccoutService.

The only question left to answer is, how do we inject the AccoutService into the Default.aspx.cs. 

Step - 3 - Configure the dependencies of Page Default.aspx in web.xml


For configuring the AccoutService dependency in Default.aspx we have to add the following object declaration in web.xml
Notice that we simply have to add the declaration of Default.aspx with proper path in web.xml. Since, Default.aspx is located in the Pages directory, we have to refer it as ~/Pages/Default.aspx. We have to add all the dependencies for the page, just like how we do it for other Spring.NET objects.

All set, lets test our setup and browser the page Default.aspx to see the result.
Enabled Dependency Injection in web.forms using Spring.NET
As you can see, we are able to see the user count value on the page.  We have successfully Enabled Dependency Injection in Web-Forms Web Pages.

Lets quickly see how we can enable dependency injection in User Controls.  Steps to do that are as follows:
  • Create a user control called UserCount.ascx that invokes AccountService to get the user count
  • Update the Default.aspx to use the UserCount.ascx user control
  • Configure the UserCount.ascx in web.xml
Step - 1 - Create a user control called UserCount.ascx that invokes AccountService to get the user count 

We are going to create a very simple user control.  Let's call it UserCont.ascx.  This user control will simply fetch the user count using the AccountService and show it on the UI.
The code of UserCount.ascx is very simillar to what we have already seen in Default.aspx.  We are setting the value of userCount label by invoking the UserCount() method of AccountService instance.

Notice that, we are not instantiating AccountService anywhere in the user control. We will inject it using Spring.NET.  Before we look at, how exactly we do that lets update the Default.aspx to make use of the UserCount.ascx user control.

Step - 2 - Update the Default.aspx to use the UserCount.ascx user control

Let look at the updated Default.aspx
Nothing very alarming here. We simply are including the user control UserCount.ascx and showing it on the html.

Step - 3 - Configure the UserCount.ascx in web.xml

The final step is to configure the UserCount.ascx in web.xml.  Here is how we do it.
Notice that we registered the UserCount.ascx in Spring.NET configuration file. We simply have to specify the complete path of the UserCount.ascx.  Notice that we didn't have to change the configuration for Default.aspx at all.  Spring.NET is smart enought to inject the correct instance of UserCount.ascx in Default.aspx.

Another important thing to notice is that we have to add abstract="true" to the declaration of UserCount.ascx. 

All set, let's see the setup in action


Enabled Dependency Injection in user controls using Spring.NET
As we can see, we see two lines on the page showing the UserCount, first one is getting the user count directly from Default.aspx web page, while the second line is coming from the UserCount.ascx user control.

Mission Accomplished!

Sunday, October 2, 2011

Strongly Typed Session Using MVC3 and Spring.NET - Part - 3

This is the last post in the series of posts to show How we can achieve Strongly Typed Session using MVC3 and Spring.NET.  In previous two posts (first and second) we saw what were the benefits of strongly typed session and how we could enable the session scope using Spring.NET 1.3.1.

The question that we had left unanswered in the previous post was:  

What is "session" scope supposed to do with Strongly typed sessions?

Well the session scope is the key, in this post we will see how it enables us to create a strongly typed session.

The session scope enables us, to register objects with scope=session.  Spring.NET will create one instance per user Session for objects that are configured with scope=session.  This means effectively we can use such an object to hold information that would otherwise be saved in the HTTP Session.  Since, these objects are configured in Spring.NET, they can be injected as dependencies in any other class. 

Where would we want to inject such a class?

MVC Controllers are a good place to do so.

Why? 

Because, controllers are the class that would do some business processing and then would want to set some information in the HTTP Session.

For e.g. Lets consider this scenario, we have a AuthenticationController which has a Login action.  This method takes in the username and password as argument.  This method calls the AuthenticationService to find whether the username and password combination is valid.  If the username and password are valid, AuthenticationController wants to set the username in the session so that it could be used by other pages to show user information on the page.

In our case we do not want to use the HTTP Session.  Hence, our AuthenticationController will put the username in some object, let's call it UserContext, which has been configured in Spring.NET with scope="session".

But wait,

What if two users are trying to login at the same time?  Will one thread overwrite the username saved in the UserContext by the other thread?

As the UserContext object is configured with scope="session", Spring.NET is smart enough to understand that, two requests are coming  to AuthenticationController are coming from two different user sessions, it injects two different instances of UserContext in the AutheticationController for two different user sessions.  Hence, one thread will *not* overwrite the username set in the UserContext by the other thread. 

So far so good.

What happens when, user who had logged in earlier (i.e. UserContext has the UserName property set), sends another request to the server?  How do we ensure that correct UserContext instance is injected in the Controller so that previously set UserName could be retrieved?  

Again, Spring.NET is smart enough to understand that, for the given user session an instance of UserContext was already created, Spring.NET will find the correct UserContext instance associated with the user session and injects it in other Controllers/objects that need it.  This effectively eleminates the direct use of HTTP Session for us.  We can be sure that, whatever information we set in UserContext will be specific for a given User Session and correct UserContext instance will be injected in the controller whenever we need it.

I know, at first it all looks very confusing, but lets look at the code to make things clear.

These are the steps required to configure the UserContext and AuthenticationController
  • Register the UserContext in Spring.NET configuration file with scope="session"
  • Write the implementation for the UserContext
  • Register the AuthenticationController in Spring.NET configuration flie with singleton="false".  Add to this the dependency of UserContext.
  • Write implementation of Login Action to set the UserName Property in the UserContext.  Write another action method let's call it UserInfo which will retrieve the UserName Property from the UserContext object and display it on the UI
  • Write the RazorIndex view to show the UserName from the ViewBag 
  • Test that the setup is working with two different browser windows trying to Login and access the UserInfo at the same time.  We should see correct user names being displayed based on where the request is coming from
Lets look at individual steps in detail

Register the UserContext in Spring.NET configuration file with scope="session"

Update the web.xml and add the configuration for UserContext as follows
Notice that we have registered the UserContext object with scope="session". Spring.NET will understand that the UserContext object is registered with singleton but in session scope i.e. One UserContext object per user session.

Write the implementation for the UserContext 

The UserContext class would be simple enough.
Register the AuthenticationController in Spring.NET configuration flie with singleton="false".  Add to this the dependency of UserContext

Update the web.xml to add the configuration for AuthenticationController as follows. 
Write implementation of Login Action to set the UserName Property in the UserContext

AuthenticationController will have a Login Action and UserInfo Action.  Login Action will set the UserName in the UserContext.  For demonstration purpose we will append the SessionId to the UserName.  This will show us that, when we request the login action method from two different browser windows we will see different user name on the UI.
Write the RazorIndex view to show the UserName from the ViewBag

The RazorIndex.cshtml will simply show the UserName from the ViewBag if its not null. Else it will show no user logged in yet message.
Test that the setup is working with two different browser windows trying to login and access the UserInfo at the same time

Enough theory, lets see the setup in action.  As they say,

Real test is in the real world!

Let's try and browse the URL Authentication/UserInfo from FireFox and Internet Explorer and see what happens

User not logged in - FireFox

User not logged in -IE
As the UserName is not set in UserContext we see no user name set message.

Now in IE, lets browse the URL Authentication/Login and see what happens.
User Successfully Logged in.  UserName and SessionID shown - IE
As we can see, the page redirect to the Authentication/UserInfo User name with session id is shown.

Lets reload the Authentication/UserInfo the page on FireFox.  Remember that, we have not yet visited the Login page on FireFox, but we have visited the Login page on IE.
Even after user is logged in on IE, he/she is not logged in on FireFox
Yep even though we have set the UserName in the user session started from IE, it does not effect the UserContext reference in the User Session started from FireFox.

Now lets visit the Authentication/Login URL in FireFox as well to see what happens.


Now user is logged in even in FireFox





As you can see it redirects to Authentication/UserInfo with UserName set.  Notice that the session id in FireFox window is different from the session id in IE.
Notice that the Http SessionId are different in two images

This effectively proves that UserContext reference plugged in by Spring.NET when request comes from IE is different from the one that gets plugged in when request comes in from FireFox i.e. We have successfully injected different UserContext reference per User Session. UserContext object can now be used to hold any information that would have be placed in HTTP Session. This effectively eliminates the use of HTTP Session and gets us a strongly typed object which can be used as a replacement to the HTTP Session.

That's it! we have successfully achieved Strongly Typed Session in an MVC3 application using Spring.NET.

Tuesday, September 27, 2011

Strongly Typed Session Using MVC3 And Spring.NET - Part - 2

In my previous post, we saw why its a good idea to have strongly typed HTTP Session. In this post we will do the real thing (well at least first part of the real thing).

Using Sping.NET we can control the objects lifecycle. By default the Objects configured in Spring.NET are Singleton for the entire application (singleton for scope="application"). Singleton for the entire application means, Spring.NET will create only one instance of the given object for the life-cycle of the application.  Service classes, DAO classes etc are a good fit for Singleton Pattern.

However, there are other Object Scopes that can be configured in Spring.NET.  These Scope's tell Spring.NET that, A given object is singleton but in a given scope.

One of the interesting scope is session.  Session scope is only available if we use a web-aware Spring IApplicationContext implementation.  For such objects, Spring.NET would create one instance per HTTP Session.  In this post we will see how we could take advante of the session scope, to create Strongly typed session in an MVC3 application.


Enough blabber.  Let see how exactly its done.

How do they do it!

As we had seen in one of the previous post to Integrate Spring.NET with MVC3 application, we had used the Spring.Context.Support.MvcContextHandler.  This class instantiates Spring.Context.Support.MvcApplicationContext, which in turn initializes the spring application context.

Support for session scope is porivded by spring.web.dll.  Unfortunately, as of Spring.NET 1.3.1, spring.web.mvc.dll does not depend on spring.web.dll, which effectively means, MvcApplicationContext is unaware of the session scope.

Hence, using just the MvcApplicationContext there is no way we can eable the session scope for a certain objects.  Its a bug you can find more details here.  But where there is will, there is a way!  There is obviously a way around this problem.

Here are the steps to enable full session scope support for any object in Spring.NET 1.3.1
  • Update the web.config to use a custom WebContextHandler
  • Register the spring WebSupportModule in web.config under the <httpModule> section for IIS6 and under the <modules> section for IIS7+
  • Implement the custom WebcontextHandler.  Override the property DefaultApplicationContextType.  This property informs Spring.NET about the class type of ApplicationContext that Spring.NET should instantiate.  This will be again a custom class that extends from Spring.Context.Support.MvcApplicationContext.
  • Implement the custom class that inherits from Spring.Context.Support.MvcApplicationContext.  This class will basically override two methods
    • CreateXmlObjectDefinitionReader to return the instance of WebObjectDefinitionReader
    • CreateObjectFactory to return the instance of WebObjectFactory
That's it!  We have now successfully enabled the session scope for Spring.NET 1.3.1.  Let look at the actual code.

Step - 1 - Update the web.config to use a custom WebContextHandler

Update the web.config configSection to look like

The class aspnetwebFormsWithMvc3App.Context.MvcWebContextHandler is our custom class where we will override the property DefaultApplicationContextType.

Step - 2 - Register the spring WebSupportModule in web.config under the <httpModule> section for IIS6 and under the <modules> section for IIS7+ 

Adding the spring module for IIS6 and IIS7

Step - 3 - Implement the custom WebcontextHandler

Lets look at the custom WebcontextHadler class aspnetwebFormsWithMvc3App.Context.MvcWebContextHandler

As you can see this class is pretty simple, it just overrides the property DefaultApplicationContextType to return the class type of custom WebApplicationContext.

Step - 4 - Implement the custom class that inherits from Spring.Context.Support.MvcApplicationContext

This is the class where the real work is done.
That's it! We have successfully enabled the session scope in MVC3 application using Spring.NET.

Question is: What is all this supposed to do with Strongly typed sessions?

In the next and the final post in this series, we will see how we can take advantage of session scoped objects to create the Strongly Typed Session in an MVC3 application using Spring.NET. 

Wednesday, September 21, 2011

Strongly typed Session with MVC3 and Spring.NET - Part - 1

In every Web project I have worked so far, always there is a need to store some or the other information in HTTP Session.

I am very finicky about putting things in the HTTP Session.  IMHO HTTP Session should be kept as light as possible.  There should be a very very strong and compelling reason to put a certain value in the HTTP Session.  Having said that, I do agree that there are times when we want to put certain information in the HTTP Session like user name, user id, etc.

With me so far?  Till now we understand that, we do not like to put things in HTTP Session, however, we understand that there is a definite need to put certain things in HTTP Session for the app to work correctly.

Question is, Is there an alternate to putting things in HTTP Session?

In this series of three posts we will try to answer this question.  We will try to use MVC3 and Spring.NET to eliminate the need of putting stuff in HTTP Session.

But wait a minute, let's first answer this question,

Why is putting things in HTTP Session is such a bad idea?  

Lets start by looking at the code that will put UserName into the HTTP Session.
Does it remind you of code that you have seen in one of your applicatoin? It certainly reminds me of code that is used all over the place in one of the projects that I had worked.

I totally hate to see code like this.  Why whats wrong with such code?

Session is used like a Hash Table:

In our example, key of the hash table would be UserName and value will be Git Shah.  Imagine while putting/retrieving values to/from the HTTP Session, if incorrect keys are used, results could be catastrophic.  Even a small typo like one shown in the example below would yield incorrect results
Ofcourse there are ways to get around this problem. Simplest of them is to use a Static Class that holds all the keys as constants.

However, you can still not gaurentee that every programmer on your team will always always use constant keys from the static class.  Believe me, because of human error or some other unexplainable reason, someone would use hardcoded inline key to put value in the Session and rest of the team will curse him/her for eternity! 

Session values are not strongly typed:

We have inserted a string value Git Shah in the HTTP Session against the key UserName but when we want to retrieve the value from the session we will have to typecast to its correct type.  In our example to retrieve the value of UserName key in HTTP Session code would look like
I have a name for code like that, I call it A Time Bomb!

Its just a matter of time before which you start getting a class cast exception.

Dude, whats in my Session? Where are these values used?

Can we say for sure what all values are stored in our session?  

Another important question to answer is, Can we say for sure, from what all places in the code are these values accessed?

These are a very important questions.  Answers to these questions are absolutely vital for the health of your application.

In one of the projects that I had worked, we were extremely confused for a very long period of time.  The question that was bothering us was, who was setting a specific value in the session and in what condition?

Consider an example

UserName key is populated in the LoginController.Login method. Lets look at another place where UserName is used.
AccoutController.UpdateUser updates the value of the UserName key in the HTTP Session to the new value passed as argument and AccountController.GetUserDetails method fetches the value of the UserName key from the HTTP Session and sets the ViewBag.UserName property.

As you can see in our simplistic example UserName key of the HTTP Session is used at three places.  In real life, it would be used in many more places than this.  The code that accesses the UserName key from the HTTP Session would be littered all over the place!

How will we find the exact places where UserName key is populated/fetched into/from the HTTP Session?

There is no easy way to find the exact places where UserName key of the HTTP Session is used.  We can extract a constant for the UserName and then search for its usages, but still this is not a full proof way, as I mentioned earlier, there are many fools out there who will not bother to use the constant and use an Hardcoded string key instead.

These are few of the problems that are a big concern to me.  Question to be answered is,
  • How can we avoid such code?  
  • How can we achieve an alternate option that will discourage people from writing such code?
Before we dig deeper into the solution, lets first focus on some of the design goals that this new solution should have.
  • Things that we put into and fetch from the session should be strongly typed objects.  There should not be any cast of any sort.  This will avoid Time Bomb like code.
  • Session should not be used as a Hash Table.  Whatever we put into the session should become a property of the session which can be accessed from anywhere in the code.  Moreover, because it becomes a property of the HTTP Session, we would get all sorts of intelli-sense on it.  There is no chance of any typo in this case.  For e.g. the existing code
Should no longer be required instead we should have code that looks like
  • At any point in time, it should be easy enough to find the exact places where a certain property of HTTP Session is used. In some ways this point is related to the previous point. If we are able to convert Keys of session into strongly typed Properties then we can just search for the usages of those properties and we know exactly where those properties were used!
Enough goals to start with.  Question is, Can these goals be implemented in real life? 

Well, the good news is, these goals are definitely implementable.  In fact its not too difficult to implement these goals when we use Spring.NET with MVC3. 


What is the bad news?  You will have to wait for my next posts to see how exactly we could implement these goals :)

Stay tuned folks in the next couple of posts we are going to have some fun with HTTP Session Management!

Sunday, August 28, 2011

Integrating NHibernate with Spring.NET and MVC3

We have seen in one of the previous post that its not very difficult to integrate Spring.NET with MVC3 application.  Almost every real project has a need to talk to a database for doing stuff.  When it comes to interacting with the Database, NHibernate does an Awesome job. 

I have used NHibernate with legacy database as well as databases that were designed from scratch.  IMHO, other competing products have a long way to catchup before they can be compared with the flexibility that NHibernate offers!

Recently, in one of MVC3 project we integrated NHibernate using the Fluent API with Spring.NET.  This process is not very difficult but it involves a few steps.  I decided to document the steps for the benefit of the community.

We will continue from where we left in the previous post, if you did not read the previous post already then, I strongly recommend reading it to understand how you can integrate Spring.NET with MVC3 application.

Very well than, Lets start!

To integrate NHibernate using the Fluent API in a Spring.NET MVC3 application one has to do the following
  • Make the Web.config changes to include the Parsers config section in the spring configuration.
  • Register the OpenSessionInView HTTP Module in web.config.  We will be using single session per request, NHibernate session handling strategy.
  • Add the reference to the required DLL's
  • Register the DB provider in the spring configuration file.
  • Register the NHibernate Session Factory in the spring configuration file
  • Write a custom implementation of the NHibernate Session Factory that loads and registers the Assembly that has Fluent NHibernate mappings in it.
  • Register the Transaction Manager in the spring configuration file
  • Enable the Spring AOP Transactions using attributes in the spring configuration file
  • Test out the NHibernate integration
Lets execute the steps one by one.  Please remember I will be continuing from where I left in the previous post.  Hence, I will be assuming that you already have Spring.NET correctly integrated in your MVC3 application.

Step - 1 - Make the Web.config changes to include the Parsers config section in the spring configuration

To integrate only Spring.NET with MVC3 application we had to add a configurationSection called context.  To integrate NHibernate with Spring.NET in a MVC3 application we have to add another configurationSection called parser.  This section will help Spring.NET understand the Database and Transaction configuration.  Lets look at how its done.

Step - 2 - Register the OpenSessionInViewModule HTTP Module in web.config. We will be using single session per request, NHibernate session handling strategy

Why do we need the OpenSessionInViewModule HTTP Module?

This will ensure that before the request is processed by any Controller, NHibernate session is opened and attached to the current thread.  And just before sending the response to the client, the NHibernate Session will be flushed and closed.  This enables us to do lazy loading even when the View is being rendering.  Lets look at the web.config change required to enable this:

Step - 3 - Add the reference to the required DLL's

For integrating NHibernate with Spring.NET and MVC3 application we need to add the references of following spring DLL's
  • Spring.AOP.dll -> Used to enable AOP using Spring.NET.  This will be heavily used when we enable transactions in our application.
  • Spring.Data.dll -> Used to enable the Spring.NET Database module
  • Spring.Data.NHibernate30.dll -> Used to integrate Spring.NET with NHibernate
  • NHibernate.dll -> The core NHibernate DLL
  • Iesi.Collections.dll -> Provides the ISet interface and its implementation
  • FluentNHibernate.dll -> Used to enable FluentNhibernate configuration for NHibernate
  • log4net.dll -> Used by NHibernate for logging.  Lot of effort has been put into making the NHibernate log as detail as possible and as readable as possible.  This is a great tool when it comes to debugging something that you cannot understand easily
  • NHibernate.ByteCode.Castle.dll -> Used by NHibernate to enable Dynamic Proxies
  • Castle.Core.dll -> Used by NHibernate to enable Dynamic Proxies using Castle
Step - 4 - Register the DB provider in the spring configuration file

This step is pretty simple.  We need to inform NHibernate about the Database.  This is done by registering a DbProvider in the spring configuration file.  We will be registering the DbProvider in the web.xml (web.xml was the file we created in the previous post.  This hold all the Spring.NET configuration).  Add following configuration to the web.xml

Notice that we have to define the db name space in the objects root tag. Please update the above configuration with the DB Credentials that you are using.

Step - 5 - Register the NHibernate session Factory in the spring configuration file

Session Factory is a heavy weight NHibernate object.  Only one instance of SessionFactory is create per database.  Lets look at the Spring.NET configuration file for registering the NHibernate Session Factory.

The above configuration registers a NHibernate session factory which is of type aspnetwebFormsWithMvc3App.NHibernate.FluentNhibernateLocalSessionFactoryObject and is found in the assembly aspnetwebFormsWithMvc3App.  This is a custom class that we will create later in the post.  It has various properties like
  • Which DbProvider to use
  • What are the FluentNhibernateMappingAssemblies.  This is a list of assembly names which our NHibernate Session factory class will search for to locate Fluent Nhibernate mappings
  • What are the MappingAssemblies.  This is a list of assembly names which has normal NHibernate mappings
  • What are the HibernateProperties.  These are the key value pairs of NHibernate properties that we would want to use.  We are setting the connection provider, dialect, driver_class and sql_sql values
Step - 6 - Write a custom implementation of the NHibernate session factory that loads and registers the Assembly that has Fluent NHibernate mappings in it

We have to provide a custom implementation of NHibernate Session Factory class so that we could load our Fluent NHibernate assemblies.  These assemblies will have the Fluent NHibernate mapping classes.  The code of our Custom NHibernate Session Factory looks like this

Step - 7 - Register the Transaction manager in the spring configuration file

NHibernate always interacts with the database using Transactions.  We would definitely want to control how and when the transactions are started and ended.  For that to happen we need to register the transaction manager in the spring configuration file.  Add the following to the web.xml spring configuration file.

Step - 8 - Enable the Spring AOP transactions using attributes in the spring configuration file

We would want to govern how and when the transactions are started using Attributes.  For this to happen we need to inform Spring.NET that we are going to use Attributes to define the transactional behavior we need.  Spring.NET reads these attributes and starts/commits/rollbacks transactions using AOP.  To inform spring.net about our intentions add the following line in web.xml spring configuration file.

Notice that we added the line tx:attribute-driven but we also added the namespace tx in the objects root node declaration.

If you have followed all the steps so far then you have successfully Integrated NHibernate with Spring.NET in an MVC3 application.

Step - 9 - Test out the NHibernate integration

To test out our brand new NHibernate integration with Spring.NET in an MVC3 application, lets change the implementation of the AccountService.UserCount method.  Currently the AccountService.UserCount method returns a hard coded value of 5454.  We will now replace it with the correct implementation, we will get the record count from the User table.

We will have to create an NHibernate entity that maps to the User table.  Lets create the User class that will map to the User table.  We will also create a class called UserMap class that will hold the NHibernate Fluent Mappings for the User class.

The details are embedded in comments. We have the User entity class and the UserMap mapping class to hold Fluent NHibernate mappings.

Now, its time to actually use the User class to get the count of number of users in the database.  To do that, we will have to inject the SessionFactory instance in the AccountService.  Updated Spring.NET configuration file web.xml would look like

After injecting the SessionFactory its time now to change the implementation of the UserCount method to return the count of users from the users table. Updated AccountService looks like

Since we have registered the OpenSessionInViewModule HTTP Module the GetCurrentSession method of SessionFactory instance will return the same session instance that was created by the HTTP Module. This is absolutely vital for the Lazy loading to work correctly.

Also notice that we have added the [Transaction] attribute to the method UserCount with TransactionPropagation as Required.  This will make sure that whenever the method UserCout is invoked either a new transaction is started or the method will join any existing transaction started earlier in the same thread.

All set!  Its time to run the server and browse the /Home/SpringIndex URL to see if our integration with NHibernate works!
Showing the actual user count using NHibernate
As show in the image we are successfully getting the UserCount from the database.  We have successfully integrated NHibernate with Spring.NET in an MVC3 application!

Saturday, August 13, 2011

Integrating Spring.net with MVC3

If you are doing any kind of serious project, you sure want to use some sort of dependency injection.

Why do I need dependency injection?

Lot's of people have written lot's about why dependency injection is required.  I am not going to repeat all that, just a few points that I think, cannot be ignored

  • Configuration flexibility - alternative implementations of a given service can be used without recompiling code
  • Testability - Since we can provide alternative implementation of any given service at any time, any class can be unit tested very easily and effectively.  Its easy to inject a fack implementation of a service in the class we want to unit test
  • Reduction of Boiler plate code - Since we no longer need to create instances of classes and inject them with proper dependencies
  • Promotes loose coupling between classes and subsystems - Since classes are not dependent on a specific implementation, they are dependent on the contract that the other classes expose.
Enough said about dependency injection.  At this point if you are still not convinced that you need dependency injection, then I strongly recommend reading the full series of posts on Dependency Injection from Fabien Potencier here

Alright, so we need dependency injection, what next?

How do we implement dependency injection?  Should we hand code the logic and create our own way of doing dependency injection?

Well, take my advice, never ever, never every do that!  Always look for options, you will surely find one depdendency injection framework/container that suites your requirements.  Even if it does not fit your requirement completely, I am sure the framework/container provides enough hooks, based on which you can customize it to you taste!
In the year 2011 and beyond, you cannot be serious if you are wasting your time and someone Else's money writing a dependency injection framework (I know a few people who have done that, can you believe it!)

What is Spring.NET?

Spring.NET is an awesome dependency injection framework (actually its lot more than that).  Its open-source and its design is based on the proven Java based Spring Framework.  The breath of functionality in Spring .NET spans application tiers which allows you to treat it as a "one stop shop" but that is not required.  The best thing about Spring .NET is, its not an all-or-nothing solution.  You can use the functionality in its modules independently.  Spring.NET integrates with a lot of other projects like NHibernate, NUnit, Active MQ, Quartz .NET, Velocity etc.


Enough about Spring.NET, if you want to know more details about Spring.NET, I strongly recommend visiting this site, it has all the info you need.  It has links to the latest documentation, blogs, articles, faq's etc.

By this time we agree that, we should use a dependency injection framework and for the sake of this post, I am going to show how easily we can integrate the Spring.NET dependency injection framework in our MVC3 application.  Lets not waste any more time and jump into the code straightaway to get this part started, shall we!


How do they do it?

To Integrate Spring.NET into the MVC3 application you will need to do the following steps
  • Add the Spring.NET dependencies to the project.
  • Make the web.cofig changes to register the spring context
  • Declare the dependencies in an xml file
  • Write the code to interact with the dependencies in the HomeController
  • Inherit the Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication
Lets have a look at each step one after the other.

Add the spring.net dependencies to the project

For integrating Spring.NET in your MVC3 application you will need to add references of following Spring.NET assemblies.
  • Spring.Core.dll
  • Spring.Web.dll
  • Spring.Web.Mvc.dll
These dll's can be found in the downloaded Spring.NET zip package from this link.

Make the web.config changes to register the spring context

In this step we add a <configSection> for the Spring.NET configuration.  In the spring config section we would like to register the spring context.  Update web.config should look like

What we are doing here is, telling Spring.NET to look for a file called web.xml inside the Config directory.

What will the web.xml file contain?  

It will contain the dependency injection configurations for the classes in our application. 

Declare the dependencies in an xml file

Spring will search for a file named web.xml inside the Config directory, directly under the root of you application.  Lets make sure, Spring finds the file.  Create a directory called Config at the root level of your MVC3 application and create a file called web.xml inside it.  The project structure should look somewhat like this

Project Structure with web.xml included in the project
Now, its time to register our dependencies in the web.xml.  We are going to add a very simple dependency of IAccountService that will give us total number of users in the system.  The web.xml would look like this

The web.xml is just a plain XML file that uses Spring.NET xml schema to inject the AccountService into the HomeController. We have given an id to the HomeController its Home in our case. We are also declaring that HomeController has a property Called AccountService. This property will be auto injected by the Spring.NET container with the reference of type AccountService.

Notice that the HomeController is not a singleton class.  MVC3 framework creates a new instance of the Controller every time a request comes for that controller.  Hence, Spring needs to know that, the HomeController is not supposed to be a singleton class.  This is done by adding the attribute singleton="false" in the declaration of the HomeController.

The next declaration in the web.xml is that of AccountService.  For the sake of this example this class has no dependencies.  For our example this class is going to be very simple it will return some hard coded values.

Notice that the singleton attribute has not be specified for the declaration of AccountService.  By default the singleton value is true, this means that the AccountService is a singleton class.  Spring.NET will  instantiate only one instance of the AccountService for the entire application!

Write the code to interact with the dependencies in the HomeController

As seen in Step - 2, HomeController is going to have a property of type AccountService.  We are going to query the AccountService to get the user count which will be eventually be shown on the UI.

As you can see there is no magic in our classs. HomeController simply calls the AccountService to get the UserCount and sets the value in the ViewBag. The AccountService implementation is extremely simple, it returns a hardcoded value of 5454.

Lets look at the view SpringIndex.cshtml that will show the UserCount from the ViewBag.

As you must have guessed, the view could not have been any simpler. It simply shows the message with the UserCount in it.

Inherit the Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication

We are almost done with all the plumbing required to integrate Spring.NET with MVC3 but, one last thing is left.  We need to inherit our Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication instead of System.Web.HttpApplication.  This is required so that Spring registers the controller factory to instantiate the Controllers when the request comes.  This is done so that Spring gets an opportunity to dependency inject the controllers.

And we are done! Lets run the application and browse the URL /Home/SpringIndex to see what happens. If you have followed the post till this point, browsing the url will result in a page like this
SpringIndex renders with UserCount value
The User count 5454 is coming from the AccountService which we successfully injected into the HomeController.

When the request for SpringIndex action of the HomeController comes to the server  following things occur
  • Spring intercepts the call and instantiates HomeController 
  • Injects all the dependencies of HomeController i.e. AccountService in our case
  • Calls the action method SpringIndex to complete the request
  • SpringIndex method calls the AccountService to get the UserCount and sets it in the ViewBag
  • SpringIndex.cshtml is rendered which shows UserCout!
We have successfully integrated Spring.NET with a MVC3 application!  That's all folks!

Saturday, August 6, 2011

Asp.Net MVC3 and Asp.Net Web Forms Side-By-Side in One Project - With Razor Views

In The previous post, I explained how we could use MVC3 and Asp.Net Web Forms Side-By-Side in One Project.  In that post, we were rendering MVC3 pages using the ASPX View Engine.  ASPX View Engine is the legacy view engine, Razor View Engine has significant advantages over the ASPX View Engine.  In this post we will see how we could use the Razor View Engine instead of the ASPX View Engine. 

The Asp.Net MVC 3 has always supported the concept of view engines – which are the pluggable modules that implement different template syntax options.  Razor view engine is optimized around HTML generation using a code-focused templating approach.

Why Razor View engine?

Razor View engine is build with the following design goals (read the detail design goals here)
  • Compact, Expressive, and Fluid: Razor minimizes the number of characters and keystrokes required in a file, and enables a fast, fluid coding workflow. Unlike most template syntax's, you do not need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is smart enough to infer this from your code. This enables a really compact and expressive syntax which is clean, fast and fun to type.
  • Easy to Learn: Razor is easy to learn and enables you to quickly be productive. You use all your existing language and HTML skills.
  • Is not a new language: Razor enables developers to use their existing C#/VB (or other) language skills and deliver a template markup syntax that enables an awesome HTML construction workflow with language of our choice.
  • Works with any Text Editor: Razor doesn’t require a specific tool and enables you to be productive in any plain old text editor (notepad works great).  That said, I have to mention this, Resharper 6.0 has one of the best support for Razor Syntax.  Its a paid tool but its definitely worth the price.
  • Has great Intellisense: While Razor has been designed to not require a specific tool or code editor, it will have awesome statement completion support within Visual Studio.
  • Unit Testable: This is one of the most important Design Goal.  Razor implementation supports the ability to unit test views (without requiring a controller or web-server and can be hosted in any unit test project – no special app-domain required).
If you want to see a detailed reasoning of why Razor is better then ASPX View Engine, I strongly recommend vising this link

Now that we are convinced that, Razor View Engine is better than ASPX View Engine, lets integrate the Razor views in our Asp.Net Web Forms application with MVC3 integrated in it.

How Do they do it?

Initially, I though there must be setting somewhere in the project properties which will enable us to use the Razor View Engine, however, after several wasteful minutes of searching and researching in the project properties I found that, there is no such setting, we can directly go ahead and create the Razor view in the project.

Razor views have an extension of cshtml.  Lets create our first Razor view called RazorIndex.cshtml right next to the Index.aspx that we had created in the previous post.  This view will have nothing special, it will display one message that we set in the ViewBag.

Notice that we are displaying the UserName from the ViewBag.  Notice that, in the new Razor syntax, we have to use the @ sign to access any objects and properties.

Let's add one more method in our HomeController which will render the RazorIndex view and set the UserName in the ViewBag.  The controller code will look no different from how it looked for rendering ASPX pages.

This is a very good example of showing, how well the Seperation of Concerns Design Pattern has been implemented in MVC3.  Even though we want to use a different View Engine, controller code remains unchanged.  In fact, Controller has no idea about which View Engine will be used to render the view.  This is an excellent example of why things should be loosely coupled to achieve modular and clean code!

Before we can see if our Razor view is rendered correctly or not let's not forget to add one more route to our routes collection in Global.asax.cs file

We have just added one route called RazorHome. All set! Lets build the project and access the URL /home/razorindex and see whats the outcome.
First attempt to render Razor View results in an compilation error
OK does not look too good.  The error states that The type or namespace name 'Helpers' does not exist in the namespace 'System.Web'  To fix this we will have to do a change in the web.config.  We will need to add a few assemblies in the  <system.web><compilation> section.  The updated web.config would look like

After this lets build and access the URL /home/razorindex and les see what happens
Second attempt at rendering the Razor view also results in compilation error, this time it cribs for ViewBag
Still not quite there, but getting closer.  This time the error says that The name 'ViewBag' does not exist in the current context.  The problem is that the compiled class RazorIndex_cshtml is extending System.Web.WebPages.WebPage class.  As we had seen in the previous post, MVC views needs to extend from System.Web.Mvc.WebViewPage and not System.Web.WebPages.WebPage. 

How do we fix this issue?

We need to some how tell the framework that the Razor pages should extend System.Web.Mvc.WebViewPage class.  This is done by adding another web.config in the Views directory.  The project structure would now look like this
Project Structure with two web.config's
The content of this new web.config should look like

The element <pages pageBaseType="System.Web.Mvc.WebViewPage"> tells that, the Razor views will have base class of System.Web.Mvc.WebViewPage.

Lets Rebuild the app and browse the URL /home/razorindex and see what happens.
Success! Razor view renders correctly
Bingo!  We have an Asp.Net Web Forms application with MVC3 Razor views integrated in it!

PS: Now you have no reason to not move to ASP.NET MVC3 from Web Forms, we have proved that MVC3 can co-exist with a Web Forms in the same project!
Have some Fun!