Naked MVVM – simplest way to do WCF code
How to get testable WCF code in simplest way?
What is the problem?
We all know that creating an instance of service proxy inside of the view model makes writing tests for the view model very hard because during the unit test run we don’t have usually the web service on the other side or even if we do it slows down web tests.
You know how they say
“Unit test is the test which runs without any problem with network cable unplugged”
Like the previous post about simplest possible way to do MVVM, the solution for this problem was covered in so many blog posts that even I am personally aware of a couple of cool and ‘frameworkish’ ways to solve it: use WCF behaviors, create your own ChannelFactory<T> with either sync call in separate thread or IAsyncResult based approach and (my personal favorite) hack the Visual Studio proxy generator. I’m sure there are at least 24 more solutions to do this ![]()
Still, there are two main problems with all the approaches I saw which belong to one of the next two groups:
- They deal purely with async based scenarios.
If I have a service with a method GetForecast(DateTime date), I don’t want to maintain another interface just to get a way to make async call. - They are rocket science type of solutions
We are all geeks and like nice and shiny toys, but what about regular folks like me and a lot of the readers? Is there a really simple way to do this for “us others”?
Luckily, I think I found one which is definitely not the coolest one and 100% can be enhanced etc, but it is the one which proved to me in my day to day WPF/SL coding to be the easiest one “to grok and use”.
Conceptual solution
The solution follows next design goals:
- doesn’t require any typing
- it is using Visual Studio proxy generated with “Add service..” menu action
- it is using the well documented MethodAsync() invoker, MethodCompleted event subscriber pattern
- it is using T4 to auto generate code which enhances the VS generated service proxy
- every service proxy file follows naming convention of ending with word “Proxy”
A year ago, I have blogged in great detail about the unfortunate fact of ServiceClient generated in service proxy not implementing an IServiceClient interface. In case you want to understand what my solution do under the hood go read that blog post now and then continue reading this one. In case “you don’t care how it works as long it is working” here’s a very short summary for you:
ServiceClient generated by proxy generator is marked as partial class.That allows me to create another partial class with same name and namespace outside of proxy which only purpose is to hook the IServiceClient interface I generated manually based on the ServiceClient itself.
In the original blog post I do it manually which ended as a PITA due to the fact that every change of service contract one has to keep updated the interface. As a result of noticing that I waste a lot of time on that, I spent 20 minutes and created a simple T4 class which does that automatically for me.
You can download the source code of end solution here.
Before
Project structure is very trivial. It is vanilla Silverlight project which has a TimerService WCF service doing just this
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
namespace NakedMVVM.Web
{
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TimerService
{
[OperationContract]
public string GetTime()
{
return "Yes it works on " + DateTime.Now;
}
}
}
Once we add a service proxy to NMVVM_WCF project (NOTE that proxy name ends with Proxy)
We can happily write now our demoware code “…
namespace NMVVM_WCF
{
using System.ComponentModel;
using System.Runtime.Serialization;
using NMVVM_WCF.TimerServiceProxy;
public class MainPageViewModel : INotifyPropertyChanged
{
public MainPageViewModel()
{
TimerServiceClient client = new TimerServiceClient();
client.GetTimeCompleted += OnGetTimeCompleted;
client.GetTimeAsync();
}
private void OnGetTimeCompleted(object sender, GetTimeCompletedEventArgs e)
{
Message = e.Result;
}
[DataMember]
private string message;
public string Message
{
get
{
return this.message;
}
set
{
if (this.message == value)
{
return;
}
this.message = value;
this.OnPropertyChanged("Message");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Nothing wrong with this code per se, just it makes unit testing of the view model much harder task then it should be…
After
To fix this problem, let’s do next 2 steps:
- download the T4 template file (no need to look in what it contains at all) from here .
- add the file to the root folder of NMVVM_WCF project using VS IDE “Add existing item”
As a result of this activities t4 template was executed and a file with ClientEnhancer was auto-generated with next content
namespace NMVVM_WCF.TimerServiceProxy
{
public partial interface ITimerServiceClient
{
#region Events
event System.EventHandler GetTimeCompleted;
event System.EventHandler OpenCompleted;
event System.EventHandler CloseCompleted;
#endregion Events
#region Methods
void GetTimeAsync();
void GetTimeAsync(object userState);
void OpenAsync();
void OpenAsync(object userState);
void CloseAsync();
void CloseAsync(object userState);
#endregion Methods
}
public partial class TimerServiceClient : ITimerServiceClient
{
}
}
As you can guess, that's complete code I was coding by hand and keep it updated manually with service contract changes. Having this in place it is quite easy to change ViewModel to accept the IServiceClient as a constructor parameter
public MainPageViewModel(ITimerServiceClient client)
{
client.GetTimeCompleted += OnGetTimeCompleted;
client.GetTimeAsync();
}
private void OnGetTimeCompleted(object sender, GetTimeCompletedEventArgs e)
{
Message = e.Result;
}
The only thing left is to update the MainPage.xaml.cs file
namespace NMVVM_WCF
{
using NMVVM_WCF.TimerServiceProxy;
public partial class MainPage
{
public MainPage()
{
InitializeComponent();
DataContext = new MainPageViewModel(new TimerServiceClient());
}
}
}
And that’s it – application works like it was and we have a highly testable view model using only service client interface which is easy to stub/mock.
Having a hard time figuring out path from “before” to “after”? Here’s a short video showing step by step things just described
You can download the source code of end solution here.
Aftermath
My own version of this T4 template, beside the T4 template code used in this blog post is also auto filling IoC container with mappings to all of service clients and its interfaces generated by template. That auto generation combined with auto MVVM wire up I described in first post allow me to have this “TDD enabling of WCF service proxies” fully automated.
I decided not to put that additional template code so it won’t bloat the post with IoC containers etc, but it is VERY easy to modify and customize the T4 template – even if you never did it spend 20 minutes looking at .tt file I shared for this post and I guarantee you – you’ll get it.
The only downside of this approach is that you have to manually drop the T4 template file to every project with service proxies which in my case is not the problem at all – I add it once and after that it keeps things in sync on its own.
I am really not sure why Microsoft is not doing this in the default proxy generation process – it is not breaking anything or damaging backward compatibility and it enables easy testing. I was experimenting modifying the Visual Studio proxy generator myself, but I decided to abandon it (even it was working at the end) due to required registry modifications etc. In my opinion, dropping one file in project without any other requirements to make it testable is more transparent then other approaches and everyone could do this.
What do you think about it? Is it simple enough?
What is wrong with Cosmopolitan theme
I am HUGHE fan of Metro design paradigm, so I was more then excited to check out Silverlight business application theme pack containing the Metro theme template (“Cosmopolitan”) which was released officially couple of days ago.
I am not designer but still wanted to share with community my initial impression and that is: WTF.
Here is picture illustrating why..
Considering the fact that we are speaking here about the web site, the fact that there’s 300 pixel of wasted vertical space (~220 in OOB scenarios) is insane. Think about how usable this site would be used in typical netbook/laptop/slate (any smaller height wide screen).
What they should do is simply copy paste Zune minimalist approach which preserves the UI waste and maximize the central part of the screen showing content.
I am aware that this is template which can be customized etc, but we all know that in a lot of cases it won’t be customized at all and we might end with a bunch of web sites using “Metro theme” (especially once WP7 would be released) which would contribute to Silverlight reputation in a bad way,
In other words, while I really appreciate templates provided to us, I think Microsoft creative ninjas (or someone from the community) should do a couple more iterations on Cosmopolitan template and make it more usable by default and then we would customize it with 2nd level menu etc.
5 reasons why Silverlight sucks in LOB (compared to WPF)
Recently, Brian Noyes and Rob Relyea have touched the “WPF VS Silverlight” subject and considering the fact I was also recently thinking about it I wanted to share my thoughts on that topic too.
As I said in previous post, I’ve started at home blogging about the accountingLOB applications in Serbia and one of the questions I got challenged by one of my readers (who knows how BIG Silverlight fan I am) is
“Would you be using Silverlight for your own accountingLOB application?”
Initially answer looked very clear to me: with all the improvements Silverlight 4 brought to LOB game, desktop like programming model and web deployment looks like a perfect fit for public facing application (outside of intranets)
But, after doing some more thinking on this subject, to my surprise I came up with the opposite conclusion:
WPF is better choice for serious LOB applications.
And here are 5 most important reasons why I think like this:
Silverlight 4 is not cross platform environment any more
The biggest advantage SL had over the WPF (in my mind at least) is ability to be deployed to non-windows machines (MacOS and Linux powered machines).
Having Silverlight 4 with a whole slew of COM+ dependable features virtually prevents creating a Silverlight 4 siteapplication which would run on Mac and Linux. At least, that is the state as of today I am aware – somebody please correct me if I am wrong in this.
The way I see this change is that Silverlight 4 is shifting toward being unique “cross-screen” (desktop, mobile and TV) platform which is perfectly fine with me just it doesn’t have any particular value in context of LOB applications).
UPDATE: I did found a couple of folks with Mac which were kind enough to tell me that on Silverlight.net site there is Silverlight 4 plug-in for Mac which (as long as COM+ features are not used) works fine.
Silverlight adoption rate is not good enough
According to later RIA Stats adoption rate of Silverlight is around 60%. I’ll put aside the fact that I am not seeing that number around me in Czech Republic and accept it as correct one with slightly different interpretation: 40% of PCs are not having Silverlight installed.
The funniest thing is that WPF has 99% adoption rate because every PC with Windows newer then Windows XP SP2 (including Vista and Windows 7) has WPF installed on it. I am not sure how many Windows 2000 and Windows 98 machines are out there but whatever the number that is personally I don’t think anyone should care targeting that segment as very unlikely to invest any money in purchasing your LOB product.
Even if a PC is not having the .NET framework at all, the download size to get it on PC is just 28 MB which is bigger then 9 Mb size of MacOs Silverlight 3 plug in but who cares (with any non dial up connection it is matter of seconds). In my personal opinion, this is one of the most important WPF features in .NET 4
Silverlight tooling is good enough. WPF tooling is better
Starting with VS 2010 and Blend 4 we can work in SL4 and Silverlight is getting much more attention (just look at the paces of silverlight and wpf toolkits and everything gets to be clear there) but using WPF allows me to use all of the memory profilers, dbg viewers, any framework I want etc. If you are in doubt what exactly I think with this here’s an example: Silverlight does support printing but in case of serious LOB applications you need all the muscle WPF offers. Think something like Crystal Reports for example.
Silverlight programming model is more constrained then the WPF one
Doing Silverlight applications, one is forced to adopt the “make async web service call and get a chunk of data and do something with it” which in my personal experience limits the productivity of LOB developer compared to the speed he has developing with WPF . There’s no direct access to DB (which is actually great) but that ignores the fact that some LOB applications might need just that. For example, application can be written to target local SQL CompactExpress which then is set up to replicatemerge deltas with the central enterprise server. Anything like that (and we know how this things can get crazy in enterprises) is not possible in Silverlight.
Another thing related to this is aspect of offline access. I am aware that Silverlight 4 does have isolated storage and yes it has a bunch of open source DBs sitting on top of it, but it is just a single user storage. In reality, quite often in serious LOB applications we are seeing office andor P2P network topologies where it is essential that you have a “proxy per office” or ability to sync directly the data of “user X”. I know that Sync Framework is coming for Silverlight in 2010 but it is not there now and I am not sure if it would support topologies other then client <->(Azure) server.
Silverlight is still technically inferior to WPF in some areas.
Read Brian's post to see what this point is about.
Conclusion
Now you heard 5 of my most important reasons why I choose to stick with WPF on this. Am I missing the point? Making a false statement? Do you have more reasons in favor of WPF or Silverlight?
Looking forward to hear the comments
Asking the right questions while interviewing developers
Just another fizzbuzz interview question
I really hate interviews regardless on which side of the table I am sitting during them(Ok, it is a bit easier when you interview candidates
)
One of the main reasons why I hate them is the stupidity of the programming trivia and questions being usually asked: all sorts of binary tree related traversals, converting numbers from one base to another, number sequences etc… I mean, who really cares about that stuff in everyday's work?? Am I applying for mathematician job or for a developer one?
I have a feeling those questions are created to fresh grads because they don’t have much real world experiences but that’s just me guessing..,
But, not all of the interview questions are stupid and the most famous example of what I find to be a good type of interview question is famous “fizzbuzz problem” described by Jeff Atwood and Scott Hanselman which is an example of very simple task which resolution is purely related on persons real-world like thinking skills and not related at all to any other type of knowledge.
Couple of years ago I’ve stumbled on a video recording of a session made by Brad Adams regarding his excellent Framework Design Guidelines book where he mentioned an example which looked so trivial to me that I quickly discarded it as very obvious to literally everyone. (I couldn’t find that link for this blog post
)
Couple of months after that I was interviewing a candidate for one senior position and due to the fact he gave fuzzy answers making me wondering if he gets heap and stack so I took Brad’s example idea and came out with a simple question looking something like this
namespace InterviewTrivia
{
public class ClassA
{
public override string ToString()
{
return "Hello from class A";
}
}
public class ClassB : ClassA
{
public override string ToString()
{
return "Hello from class B";
}
}
public class ClassC : ClassB
{
public override string ToString()
{
return "Hello from class C";
}
}
}
Nothing fancy here just 3 classes inheriting from each other and each one overriding object ToString() method
Now the console application Program class can be done something like this:
using System;
namespace InterviewTrivia
{
class Program
{
static void Main(string[] args)
{
ClassA first = new ClassC();
ClassC second = new ClassC();
ClassB third = (ClassB)second;
ClassA fourth = (ClassA)third;
object fifth = (object)fourth;
Console.WriteLine("1: " + first.ToString());
Console.WriteLine("2: " + second.ToString());
Console.WriteLine("3: " + third.ToString());
Console.WriteLine("4: " + fourth.ToString());
Console.WriteLine("5: " + fifth.ToString());
Console.ReadLine();
}
}
}
As you can see there, first 5 lines are doing different variants of casting class c instance and then printing out the result of ToString() method.
I wrote this sample on a whiteboard (to avoid having R# helping him with the answer) and ask the candidate what would be the resulting output of an app.
Why is this fizzbuzz question?
Because it is:
- very simple problem and code sample
- focused on concrete programming scenario pinpointing the (IMHO) important OOP concepts which need to be understood by senior developers
- in order to solve it one doesn’t need any knowledge other then programming skills.
- it is white board friendly – very important attribute for DEV interviews
So, what happened?
To my surprise that candidate bluntly failed the test reporting as a result:
- “Hello from ClassA”
- “Hello from ClassC”
- “Hello from ClassB”
- “Hello from ClassA”
- “InterviewTrivia.ClassA”
I was done with the interview convinced this candidate was exceptionally bad and I’ve stayed convinced in that until accidentally I’ve run the same sample with couple of other developers and in most cases got the same answer as the candidate gave. That fact is maybe just the result that we .NET developers are really spoiled and allowed to be blissfully ignorant about how stack and heap in .NET works (which is btw the thing I strongly disagree), but that is not the point of this blog post.
The point is that with properly chosen trivia and programming questions we are using in interviews we can avoid loosing good candidates just because they don’t know for sure how to convert –1234.56 to hexadecimal base number (even on paper) and focus on getting information on really important attributes a new member of the team would be bringing to the team (or not) once joining the company.
(Sample code of today’s post can be found here)
| Share this post : | ![]() |
![]() |
![]() |
![]() |
Fluent NHibernate samples – Auto mapping (Part 1/2)
In my previous blog post, I have announced the sample solution with which I try to provide code sample for very comprehensive documentation which can be found on http://fluentnhibernate.org/..
The project is hosted on CodePlex (http://fnhsamples.codeplex.com/). Right now it contains just a small sample which I would use in this blog post but in the future I intend to grow it until I wouldn’t cover most of the interesting features FNH offers.
The purpose of project is just to demo how fluent nhibernate mappings work so you can quickly “get them” and NOT:
- to teach on how NHibernate works (buy this book for that)
- to teach you in detail about fluent nhibernate (go to http://www.fluentnhibernate.org for that)
- to teach about best practices in abstracting NHibernate dependencies (you can find that here)
- to teach about best practices in domain modeling etc
I am also by no means an expert in neither nhibernate nor fluent nhibernate. In fact I am just a grunt like many of you reading this blog post who was searching for similar blog post when he was banging his head against the wall trying to learn how to use it - 1+ year ago very little docs) so take EVERYTHING I say with a grain of salt.
I am also aware of the state of my English, but I am really doing my best and if anyone wants to help editing the blog post I would put that version in code plex
So, let’s start…
An example of Fluent NHibernate auto mapping in action
So, here’s the domain model I’ll be using in this blog post to show couple of FNH auto mapping aspects
And here’s the database model which would be created after the sample would be executed based on fluent nhibernate auto mapping conventions.
(To get more details about the domain design check the use case description from previous blog post)
Convention over the configuration
FNH auto mapping works based on applying the convention over the configuration which I usually try to explain like this…
“There is a set of rules which would be applied to your domain during its mapping to database model.
Here are couple of examples of rulesconventions:
- Database table would be named used plural form of the entity name.
- Primary key of every table would be named following the rule “entity name” + “ID”
Fluent NHibernate comes with a default set of rules which you can customize to your own preferences on a very cool and easy way.
Sounds simple? It is THAT simple.”
Let' see quickly how the fluent nhibernate magic happens.
How the Fluent NHibernate Auto mapping magic works (explanation for us others)?
I won’t go deep into the details (for that go to http://fluentnhibernate.org or How FNH works?) but in general it is based on two design patterns: Proxy and Visitor.
If you are not familiar with the patterns here’s a simple way for you to get them in the context of fluent nhibernate magic.
The role of proxy design pattern in fluent nhibernate
If you check out some of the entities in Vuscode.FNHSamples.Domain project you would see that all of them are non sealed classes with all of the members being virtual… So, the code like this
namespace Vuscode.FNHSamples.Domain
{
public class Address
{
public virtual string Email { get; set; }
public virtual string City { get; set; }
public virtual string Country { get; set; }
}
}
The reason why we HAVE TO respect this rules designing our domain classes is related to the fact that FNH uses castle dynamic proxy functionalities to (in overly simplified version) create an “in memory” proxy child class by inheriting the real one and overriding the properties in the proxy child class in order to enable intercepting their calls.
In this example therefore inside of the FNH engine there would be created a “ProxyAddress” class inheriting from the Address class but which would have implemented additional interfaces and override members effectively adding during the run time behaviors and shapes to original Address class. That’s how a POCO can be achieved: we don’t need any attributes, no special base class or base interface etc..
Now, in order to understand why FNH needs this we need to take a quick peek at how FNH “mapping rules” (properly called conventions) are implemented.
How the fluent nhibernate conventions are implemented?
Always on the same way (thanks to brilliant work of FNH authors): always inherit and implement a special interface which has a method accepting a parameter of certain interface type.
public class ClassConvention : IClassConvention
{
public void Apply(IClassInstance instance)
{
// do something with instance
}
}
The reason why our convention has to implement certain interface is due to the fact that during the run time fluent nhibernate would iterate over all of the types of the given assembly and collect “all of the types implementing the IClassConvention” thus “collecting the rules”.
The reason why a IClassInstance parameter was passed is that the Apply method would get SOMETHING implementing that interface without knowingcaring about what that something really is.
This design approach where you enable your class to work with various entities without coupling to its concrete implementation can be roughly called visitor pattern.
If I use gain the same sample of Address and “AddressProxy” class, imagine that AddressProxyClass created on the fly implements the IClassInstance interface. Wouldn’t that enable us to pass an instance of addressProxy class to ClassConvention Apply method so it could perform its functionality on it?
The end result of those two patterns is that instance Address class ends inside of the Convention Apply method without adding anything to domain other then virtual keywords on properties.
Iterating, iterating, iterating…
During the runtime mapping process FNH (overly simplified) iterates over all of the types and creates their proxies.
Every proxy gets added certain interfaces which define methods allowing “outer world” to alter the state of proxy.
Fluent NHibernate (or user) then creates a collection of conventions defining the rules how certain aspects of proxies should be altered.
Now the code iterates every proxy and for every proxy it iterates over all of the conventions and applies the one matching the proxy.
As the end result of that iteration, we gat all of the proxies with their state sets up in proper state.
Then FNH iterates all of the proxies again and translates states of each one of them to NHibernate required XML representation.
Brilliant, isn’t it?
Back to reality
Now when I (hopefully) explained how NHibernate works in layman’s terms, we can just go over the conventions I have in my sample and provide explanation what is the relationship between them with certain pieces of my sample.
Class Convention
This is convention which tells to Fluent NHibernate how to map entities to database tables.
I have only one rule related to that:”A table name should be plural form of the entity name”, so the code doing that is pretty simple
namespace Vuscode.Framework.NHibernate.Conventions
{
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
public class ClassConvention : IClassConvention
{
public void Apply(IClassInstance instance)
{
instance.Table(Inflector.Pluralize(instance.EntityType.Name));
}
}
}
IClassInstance has two key members (key in sense of this sample):
- EntityType – providing access to a type being mapped to database table
- Table(name) – method which sets the value of the table name.
(To explore capabilities outside of my sample use intellisense which in case of fluent interfaces is your best friend)
Inflector is just a helper class I took from Castle.ActiveRecord project (been a long time ago) and which purpose is to get plural form of a given string. I put it also in sample project so you can check it out if you wish.
So, now when we know all of the pieces we can read the implementation inside of Apply method like this
“Make sure that whatever the proxy was sent it would be mapped in a data table which name would be plural form of the original class proxy was created from”
(Due to the fact every convention is implemented in same manner implement a interface and get something injected I’ll skip repeating that in other conventions)
DefaultStringPropertyConvention
This is convention which tells how class string properties should be mapped in database column.
My rules are simple: default length 100 and every string can be null value.
namespace Vuscode.Framework.NHibernate.Conventions
{
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
public class DefaultStringPropertyConvention : IPropertyConvention
{
public void Apply(IPropertyInstance instance)
{
instance.Length(100);
instance.Nullable();
}
}
}
Foreign Key Convention
This is convention which defines how fluent nhibernate should behave while mapping association properties to foreign keys.
My rule is simple:”Name of the foreign key is name of the table being referenced + ID suffix”
Here’s the code from sample
using System;
using FluentNHibernate.Conventions;
using System.Reflection;
namespace Vuscode.Framework.NHibernate.Conventions
{
public class CustomForeignKeyConvention : ForeignKeyConvention
{
protected override string GetKeyName(PropertyInfo property, Type type)
{
return property == null
? type.Name + "ID"
: property.Name + "ID";
}
}
}
As you can see from the code not exact translation of my rule so it needs some additional clarification…
The GetKeyName method accepts two parameters:
- property (holding a pointer to a property in entity referencing the “parent” entity
- type (holding a pointer to a “parent” table)
If we check out the resulting DB diagram
and how the domain implementation of Blogs looks like
using System.Collections.Generic;
namespace Vuscode.FNHSamples.Domain
{
public class Blog : Entity
{
public virtual Author Author { get; set;} // component
public virtual BlogRoll Roll { get; set; } // references
public virtual IList Posts { get; set; } // has many
public virtual string BlogTitle { get; set; }
}
}
We can clearly see that due to the fact that Blog has a Roll property pointing to parent BlogRoll, FNH took that property value + "ID" and created RollID foreign key in Blogs data table. So, that explains how FNH works in FK convention when property being sent is with non null value and leaves us with the question “how come that value can be null”?
To answer that, let we check out the other part of the resulting UML diagram representing DB interpretation of the Author class inheritance
As you can see, GuestAuthor and RegularAuthor have their foreign keys named “AuthorID” even none of those two has an explicit “parent” property like in previous case.
In other words There is no GuestAuthor.Author and RegularAuthor.Author properties but we still have the need for defining FK in their tables.
In this type of cases, ForeignKeyConvention would get a null propertyInfo value (because there is no property) and a pointer to a entity to be used with defining of database FK (in this example Author). That’s how in my sample foreign key of those tables become
Many to Many convention
This is convention which defines how fluent nhibernate should behave while mapping the N – N relationships where a class A has a collection property of class B type and the class B has a collection property of class A.
Here’s the code sample from the Vuscode.FNHSamples.Domain –> Post and Category classes
namespace Vuscode.FNHSamples.Domain
{
using System.Collections.Generic;
public class Post : Entity
{
public virtual IList Categories { get; set; } // has many to many
public virtual string Title { get; set; }
public virtual PostStatus Status { get; set; }
}
}
A Post can have many Categories
namespace Vuscode.FNHSamples.Domain
{
using System.Collections.Generic;
public class Category : Entity
{
public virtual IList Posts { get; set; } // has many to many
public virtual string Name { get; set; }
}
}
One Category can be used in many samples.
I prefer mapping Many to many relationships using the Association Table Mapping pattern where additional table is created with two foreign keys columns matching the primary keys of the associated tables.
Here’s how it looks in resulting database model with PostsToCategories table being association table.
I guess after seeing the diagram it is quite obvious to get the many to many convention I have:
Name of the association class should be like “TableNameA” + “To” + “TableNameB”.
How NOT to implement many to many relationship
As you can read in great detail here, many to many is in general combination of two 1 – N relationships which if it would be done like this
namespace Vuscode.Framework.NHibernate.Conventions
{
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
public class ManyToManyConvention : IHasManyToManyConvention
{
public void Apply(IManyToManyCollectionInstance instance)
{
instance.Table(
string.Format("{0}To{1}",
Inflector.Pluralize(instance.EntityType.Name),
Inflector.Pluralize(instance.ChildType.Name))
);
}
}
}
Would result in next database diagram state
So, we have 2 associations tables where each one of them covers their own path.
Clearly this is an overkill from Db perspective due to the fact that the same table can be used in both paths.
In NHibernate parlance that is achieved using Inverse relation type (again, you can read about it in great detail here) which in layman’s terms can be explained “when you need to map the Post –> Categories relation, pleas use the already defined Categories –> Post and just revert it”
And that’s exactly what the actual implementation in my code sample does
Here’s the code
Let see how this was implemented in the sample code
namespace Vuscode.Framework.NHibernate.Conventions
{
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
public class ManyToManyConvention : IHasManyToManyConvention
{
public void Apply(IManyToManyCollectionInstance instance)
{
if (instance.OtherSide == null)
{
instance.Table(
string.Format(
"{0}To{1}",
Inflector.Pluralize(instance.EntityType.Name),
Inflector.Pluralize(instance.ChildType.Name)));
}
else
{
instance.Inverse();
}
}
}
}
The instance.OtherSide is null in situation when there is no already defined relationship between EntityType and ChildType. In that case code uses Table method to set the name of association table respecting my naming convention TableA name + “To” + TableB name. That first if would result with PostsToCategories association table being created.
Now the FNH would iterate more (as described above) and the Post –> Category relation would be processed. When this happens, instance.OtherSide would NOT be null so instead of creating new association table FNH would map that relation as inverse to the original one.
Conclusion
This blog post become really long so I have decided to split it in two posts. In next post I’ll show a few more conventions and process of fluent configuration with switches I’ve been using in my sample
Stay tuned
Fluent NHibernate Samples on CodePlex
I’ve been using Fluent NHibernate for more then a year now and I am big fan of it.
The were only two things bothering me in FNH for all that 1+ year:
- frequent API changes (which made my fluent mapping and auto mapping blog post pretty quick completely obsolete – not to mention my code
), but when I saw how polished FNH get in 1.0 version I don’t mind any more – simply beautiful code. - lack of documentation. Don’t get me wrong - http://groups.google.com/group/fluent-nhibernate was REALLY useful most of the the time but I was allways dreaming about something like the current fluent nhibernate wiki which is simply awesome concentrated amount of useful data.
So, to me there’s no more problems with FNH left (beside a few minor bugs no one cares to answerfix) but in last couple of days I’ve accidentally find out ( here on the fnh mailing list and here on stackoverflow) that a lot of folks would like to see a sample code working with fluent nhibernate 1.0 (beside the wiki etc)
That’s why I decided to loop in some of my time today and create a sample project illustrating on a same example both fluent and auto mapping and that’s how I came with
CodePlex project - Fluent Nhibernate samples
The intention of the project is to initially focus on single sample illustrating all of the major use cases in the ‘real world’ manner and then to slowly grow so the sample would start covering more and more corner cases. Hopefully in a long term it would become a c# solution illustrating in one place all of the major FNH usage aspects.
Project can be found on this location http://fnhsamples.codeplex.com/ together with the source code downloadable as zip or SVN-checkout.
Starting solution
So, in order to start the project and based on the questions I am usually hearing mentioned regarding auto mapping I’ve came up with this simple domain model
So a domain space covers imaginary blog engine where:
- a blog roll is a group of blogs (e.g. codebetter.com),
- a blog contain one or many blog posts where every blog post can have one or many categories
- a blog is owned by a single author which can be regular author (that blog is his primary blog) or guest (where he cross post to this blog)
As you can see in this very simple domain I have cases of:
- References (N – 1 relation) where many Blogs belong to one BlogRoll (in this sample Blog mimics aggregate root)
- HasOne (1 – 1 relation) where author can have only one blog in a blog role and all blog posts of a blog are written by a single author only.
- Component where author has a complex Address value property of a Address type which (due to the fact it is not entity) we would like to map to same DB table as Author.
- Subclass (inheritance)where GuestAuthor and RegularAuthor are children of the abstract Author with each one of them having its own custom properties
- HasMany (1 – N relation) where a blog has one or many blog posts
- ManyToMany (N – N relation) where a post can be tagged with many categories and every category can be used in many posts
- Enumeration - where a post has status enumerated value column
- All entities share the same Entity base class which (contrary to Author entity) is not supposed to be mapped in a separate table
Note: I know that this domain model is far from perfect in modeling sense but that is not the point here. The point here is having a meaningful sample which would be used to showcase all the fluent nhibernate magic.
End result
Here’s how the DB model would look like created using both fluent and auto mappings
As you can see, DB diagram match pretty much the domain model and all that (in case of Auto Mapping) just by utilizing conventions without any manual defined mappings.
What next?
For the folks curious to check it out now, go to http://fnhsamples.codeplex.com/ where you can download the source currently containing only auto mapping based solution. I guess, it is so simple that most of us could get it just by looking at the small code base there.
For the rest of the people, my next blog post would present the fluent mapping based solution to get from model to DB diagram and after that auto mapping based solution. In that two blog posts, I would comment “line-by-line” so even people new to fluent nhibernate would (I hope) get it.
After that two blog posts, I would have to switch gears and (finally) spit out couple of things I came out with doing Prism development.
I hope at that moment there would be some suggestions what needs to be added to the sample so the sample would start to grow from its starting trivial size.
Prism (CAL) unit testing – How to test Prism (CAL) Event Aggregator using Rhino Mocks
I spent some time recently working with Microsoft Composite Application Guidance (A.K.A. "Prism", “CAL”) and I think it is very good platform for building composite UI by either using WPF or Silverlight.
One of its greatest advantages is that it was done in open source manner which resulted with most of the community feedback being incorporated into lightweight, testing friendly framework. Reference implementation and samples are also good but showing only static stubs based testing which is ok but not as powerful as mocking with some mocking framework.
My mocking framework of choice is Rhino Mocks and I am going to make couple of simple blog posts showing how to test Prism code using the Rhino Mocks in couple of typical every day scenarios.
And that leads us to today’s blog post…
How to test Prism (CAL) EventAggregator based code using Rhino Mocks?
SUT I’ll be using today will be as simple as possible to deliver the message.
LoggingService is service which is responsible for handling the logging of system errors in a way that:
- subscribes to system wide events which are requested to be logged without referencing the event sources
- decides if event needs to be published (based on severity)
- if it does, it formats the system event adding the time stamp etc
- calls the publishing service which is handling the publishing of formatted event
Considering the fact that in my sample we would be having various publishing services in system publishing to different targets(eventlog, flat text file) the LoggingService gets dependency injected only a component implementing the IPublishingService.
Subscription to system wide events on a decoupled manner is possible through EventAggregator design pattern which implementation is in Prism provided through IEventAggregator service.
The LogErrorEvent is an event to which LoggerService would subscribe and which carries the event argument of EventData type containing the ErrorLevel and ErrorMessage data.
Show me the code
Enough of my blabbering (and my English), code will speak for itself much better
Sample used in today's blog post can be downloaded here.
LoggingService
using System;
using System.Text;
using Microsoft.Practices.Composite.Events;
namespace Example
{
public class LoggingService
{
private readonly IEventAggregator eventAggregator;
private readonly IPublishingService publishingService;
public LoggingService(IEventAggregator eventAggregator, IPublishingService publishingService)
{
this.eventAggregator = eventAggregator;
this.publishingService = publishingService;
this.eventAggregator
.GetEvent<LogErrorEvent>()
.Subscribe(this.LogIt);
}
private void LogIt(EventData eventData)
{
if (eventData.ErrorLevel<=100)
return;
var stringBuilder = new StringBuilder();
stringBuilder
.AppendFormat("Date:{0}", DateTime.Now)
.AppendLine()
.Append(eventData.ErrorMessage)
.AppendLine();
this.publishingService.PublishError(stringBuilder.ToString());
}
}
}
Nothing fancy there:
- constructor accepts two parameters which provide to LoggingService access to event aggregator and publishing service through inversion of controls.
- in constructor injected event aggregator is used for subscribing of LogIt method to LogErrorEvent.
- LogIt method is private (wouldn’t work in case of Silverlight – but that is sepa rate blog post) and does next things:
- makes sure that only events with level greater then 100 get published
- formats the given error message into appropriate format
- pass the formatted message to publishing service
IPublishingService, LogErrorEvent and EventData
namespace Example
{
public interface IPublishingService
{
void PublishError(string errorMessage);
}
}
using Microsoft.Practices.Composite.Presentation.Events;
namespace Example
{
public class LogErrorEvent : CompositePresentationEvent
{
}
}
namespace Example
{
public class EventData
{
public int ErrorLevel { get; set; }
public string ErrorMessage { get; set; }
}
}
No need to waste time commenting this…
Testing the code
I could have done test first etc, but I believe that it would obfuscate the point of this blog , which now once we see the code being tested is going to be just showing the tests
Test 1 – How to make sure that event is getting subscribed
////// Shows how to verify that event aggregator subscription occurred. /// [TestMethod()] public void Ctor_Default_WouldSubscribeToLogErrorEvent() { // arrange var publishingServiceStub = MockRepository.GenerateStub<IPublishingService>(); var eventAggregatorMock = MockRepository.GenerateStub<IEventAggregator>(); var logErrorEvent = MockRepository.GenerateMock<LogErrorEvent>(); // event aggregator get event would return mocked log error event eventAggregatorMock.Stub(p => p.GetEvent<LogErrorEvent>()).Return(logErrorEvent); // expect that LogErrorEvent would be subscribed in constructor logErrorEvent .Expect(p => p.Subscribe(null)) .Return(null) .IgnoreArguments() // we don't care which exact method or action subscribed, just that there was some. .Repeat.Once(); // act var loggingService = new LoggingService(eventAggregatorMock, publishingServiceStub); // assert logErrorEvent.VerifyAllExpectations(); }
The test is using Rhino Mocks AAA syntax introduced in 3.5 version (if you don’t know it, read Rhino Mocks Documentation Wiki excellent documentation).
In Arange section test:
- defines two stubs for the services being used (stubs because I don’t care to set any expectation related to them in this test)
- defines the mock of the event which subscription I am about to check
- stubs the event aggregator behavior so on GetEvent<LoggErrorEvent>() method call would return event mock I created.
- defines expectation on that event mock that subscription would occur once (IgnoreArguments() is there because this test doesn’t care really which method exactly would subscribe to event. Test cares only that subscription had occurred)
In Act section test just constructs the service
In Assert section test triggers verifying of the event log expectations (which in this test were: someone subscribed to this event)
(Note that making test for verifying that the Publish have occurred during the test would be pretty much the same as this test with a change on mocked expectations only)
Test 2a – How to invoke event aggregator in Act test section
Sometimes there is a behavior we want to unit test which is occurring upon the event being published through IEventAggregator and because we can be using anonymous delegate, private method handling the event (case of this blog post) there is no easy way to invoke functionality which is wanted to be tested.
This test shows how to invoke event aggregator to publish the desired event which would trigger code being tested,
In case of this example we want to test that not severe errors (error level <= 100) are not getting published.
////// An example of how to trigger event aggregator in act section /// [TestMethod()] public void LogIt_ErrorLevel100_WouldNotBePublished() { // arrange var logErrorEvent = new LogErrorEvent(); var publishingServiceMock = MockRepository.GenerateMock<IPublishingService>(); var eventAggregatorStub = MockRepository.GenerateStub<IEventAggregator>(); eventAggregatorStub.Stub(p => p.GetEvent<LogErrorEvent>()).Return(logErrorEvent); // expect that publishing service would never be called publishingServiceMock .Expect(p => p.PublishError(Arg<string>.Is.Anything)) .Repeat.Never(); // act var loggingService = new LoggingService(eventAggregatorStub, publishingServiceMock); // invoke the event aggregator logErrorEvent.Publish(new EventData() { ErrorLevel = 100, ErrorMessage = "Some error message" }); // assert publishingServiceMock.VerifyAllExpectations(); }
In this test, test is having in Arrange section:
- An instance of the log error event (not the mock of that event like in the case of previous test example)
- Mock of the publishing service (in previous test we had stub) because that is service we need to check it won’t be called.
- Stub of the event aggregator with stubbed GetEvent<LogErrorEvent> method
- An expectation that PublishError method of the publishing service would never be called (regardless of the parameter being sent to that method)
In Act section test is :
- constructing the logging service injecting the event aggregator stub and mock of publishing service
- invoking the Publish method on a log error event instance passing the test data (error level == 100 in this test)
In Assert section, we are just triggering checking of expectation defined on mock of the publishing service (no call made to publish error method)
Test 2b – How to invoke event aggregator in Act test section
Although from perspective of this blog post it doesn’t have a lot of value here’s the test testing that publishing service will be called in case event will be published with error level greater then 100. (The more Rhino Mocks examples we have on web, the better adopting rate will be
)
////// An example of how to trigger event aggregator in act section /// [TestMethod()] public void LogIt_ErrorLevelGreaterThen100_WouldBePublished() { // arrange var logErrorEvent = new LogErrorEvent(); var publishingServiceMock = MockRepository.GenerateMock<IPublishingService>(); var eventAggregatorStub = MockRepository.GenerateStub<IEventAggregator>(); eventAggregatorStub.Stub(p => p.GetEvent<LogErrorEvent>()).Return(logErrorEvent); publishingServiceMock .Expect(p => p.PublishError(Arg<string>.Matches(param => param.Contains("Some error message")))) .Repeat.Once(); // act var loggingService = new LoggingService(eventAggregatorStub, publishingServiceMock); logErrorEvent.Publish(new EventData() { ErrorLevel = 101, ErrorMessage = "Some error message" }); // assert publishingServiceMock.VerifyAllExpectations(); }
Almost the same sample like previous one just with two small differences:
- In arrange section, expectation is that the PublishError method would be called once with a method parameter containing “Some error message” string (inline constrains)
- In act section, event is published with error level >100 to trigger the positive case when publishing service is been triggered
Green is nice
Conclusion
Thanks to P&P team and community feedback, CALPRISM event aggregator is implemented in such a way that mocking it is very easy (if not trivial) and every framework enabling easy testing is a good framework for me
Good work P&P!
Fluent NHibernate – Convention over configuration – AutoPersistenceModel auto map magic
Story about how fluent nhibernate idea was born
POST UPDATE: Due to changes in Auto mapping API this blog post is outdated. In order to see auto mapping in action with FNH 1.0 go check out http://blog.vuscode.com/malovicn/archive/2009/11/04/fluent-nhibernate-samples-auto-mapping-part-1-2.aspx
*******************************************************************************************************
Fluent NHibernate is an open source project (fluent NHibernate trunk) which implements fluent interface on top of the NHibernate ORM configuration capabilities which are based on xml configuration files (as most of the Java ports are) where every entity is defined in it’s own configuration file.
The main reason behind existence of the Fluent NHibernate project is that working with those configuration files is not something very productive and (in general) it is one of the major turning off points for developers trying to get NHibernate.
As I mentioned in my Using NHibernate without configuration files post, it is possible to replace the act of creation of configuration files with the c# code where instead of every configuration file defining entities we would have separate mapping class. That functionality per se is awesome improvement comparing to configuration files, but it is still cumbersome work requiring a lot of repetitive work.
Here are couple of illustration of what kind of repentance I have on my mind with previous sentence:
- My tables are having the same name as my entities (just in plural form)
- I could have 50 entity classes where every identity property would be called ID and in database I would always have primary key consisting of “table name + ID”
- Data table foreign key can be always defined following the naming rule of “parent table name + ID”
- Most of my text based columns have 255 length characters
- etc
Those rules are changing but each one of us (personally or on organization level) has a certain style of doing this things, predefined code and database standards on organization level or just agreement on team level. Based on that fact of convention existence, The Don Ayende asked for some magic to be added to Fluent NHibernate. His point was that he would like to be able to describe easily what the conventions (similar to the one I’ve enlisted above) are used in ORM area of the project and then based on those conventions fluent NHibernate should generate all of the configuration files automatically. Once those default configuration files state would be achieved, the developer would then modify configuration mappings to cover only the cases being an exception from the conventions.
Brilliant minds behind Fluent NHibernate get their heads together and implemented that AutoMap functionality Ayende was asking and I was recently playing with it and want to share my experiences with the community.
(Source code of the example used in this blog post can be found here)
Blog post set up
I’ll use the same example as the one I’ve used in Using NHibernate without configuration files post. The good side of that decision is that you would be able to see same example done on both (manual and auto map) ways but on the flip side (to understand in detail what is the use case scenario etc) you would have to read the original post because here I would just summarize it.
Class diagram
SQL Database model
Couple of major points to be noted here:
- Customer has an address (Customer.CustomerAddress property) and a collection of reference people handling his requests (References property)
- SQL Data model has two tables while class diagram has 3 classes. The difference is that Address class data on database level is embedded into customer table. In NHibernate parlance, that is called component.
- Class diagrams all have their identity property named “ID” while database primary key columns are named following the “table name + ID” rule.
- Database table names are plural form of class entities. (Customer –> Customers, ReferencePerson –> ReferencePeople)
- ReferencePerson class has property named LastName while ReferencePeople table has column named SurName
- All of the entities implement IEntity which is totally not necessary for this example andor your code but is something so commonly used that most of the examples on the web contain base entity class or interface. That’s why I added IEntity to this example to illustrate how AutoMap works in that use case too
Project structure
The project structure of the solution used in this example looks like this:
- BusinessLayer project contains entities presented in calss diagram without referencing infrastructure (PIPOCO design criteria)
NHibernateInfrastructure project contains two files:
- Inflector – this class is “borrowed” from Active Record code base and it sole purpose is to pluralize entity names to database table names
- NHibernateBootstrapper.cs is a class which performs complete initialization of NHibernate engine based on auto map and manual definitions and result with NHibernate session being created at the end of build up process. Most of this blog post would be related to this class
- NHibernateInfrastructure.Test project contains test fixture (MappingTest) similar to the one from the manual map post.
An example of Fluent NHibernate auto mapping functionality
Before I start
Unfortunately there are no official documents presenting “the right way” to do this auto mapping. Most of the examples on net are covering same trivial example and they are not very helpful too. (Btw, lack of documentation was the reason behind writing this blog post) .I am by no mean expert in fluent NHibernate so while the code presented in this blog post is fully functional there might be some better ways how to do some of the presented functionality. In other words, take the example code bellow more as a starting point and spend some time with Fluent NHibernate examining it. It would be very worth spent time, I can promise you that.
Now the disclaimer is done, let’s roll
High level overview
Here’s the content of NHibernateBootstrapper.cs class (warning: significant amount of code coming but worth of reading I hope
)
public ISessionFactory InitSessionFactory()
{
var config =
MsSqlConfiguration.MsSql2005
.ConnectionString.Is(
@"Data Source=.SQL2008;Initial Catalog=NHibernateBlog;"
+ @"Integrated Security=True")
.UseReflectionOptimizer()
.ConfigureProperties(new Configuration());// 1. defining conventions and scope of the auto persistence model
var autoPersistenceModel = GetPersistenceModelFromAutoMapping();// 2. defining exclusions form auto persistence
UpdatePersistenceModelWithExclusions(autoPersistenceModel);// 3. overriding auto mapping defaults
UpdatePersistenceModelWithManualMappingInformations(autoPersistenceModel);// 4. writing auto mapping definitions (needed just for blog post)
autoPersistenceModel.WriteMappingsTo(@"C:Temp");// 5. Configuring NHibernate configuration using auto persistence model
autoPersistenceModel.Configure(config);// returning session factory from given configuration
return config.BuildSessionFactory();
}
InitSessionFactory is the the only public method which is called from application assembly and which task is to return session factory created based on defined mapping informations.
Beginning of the method is related to creating Sql 2005 standard configuration (NHibernateBlog DB backup file is given in zip file accompanying this blog post)
Then the method perform 5 step configuration initialization:
- Create AutoPersistanceModel containing all the default mapping rules regarding how and what to auto map.
- Define domain elements which are to be excluded from the auto mapping persistence model definition due to the fact that they don’t fit to defined conventions
- Define all of the manual mapping information fore domain elements which are not auto mapped
- Write mappings xml configuration files to hard drive (not needed in production, just for you to check out the result of the fluent NHibernate auto mapping routine)
- Configure NHibernate configuration with AutoPeristenceModel initialized in steps #1 - #3
Once NHibernate is configured session factory is built and returned for further consumption.
Now when we saw high level steps, let check out how those steps look in more detail..
Creating of AutoPersistenceModel
Let see what is inside of the GetPerisicatnceModelFromAutoMapping method
namespace NHConfigMappings
{
...
private static AutoPersistenceModel GetPersistenceModelFromAutoMapping()
{
return AutoPersistenceModel.MapEntitiesFromAssemblyOf<Customer>()// defining what is to be auto mapped
.Where(type =>
typeof(IEntity).IsAssignableFrom(type)
&& type.IsClass
&& !type.IsAbstract
&& type.Namespace == "CustomerConfiguration")// defining convention attributes
.WithConvention(convention =>
{
convention.FindIdentity = p => p.Name == "ID";
convention.GetTableName = type => Inflector.Pluralize(type.Name);
convention.GetPrimaryKeyNameFromType = type => type.Name + "ID";
convention.GetForeignKeyNameOfParent = p => p.Name + "ID";
convention.DefaultStringLength = 50;
convention.OneToManyConvention = o => o.Cascade.All();
});
}
...
}
AutoPersistenceMode has a static factory method MapEntitiesFromAssemblyOf<T> where T is a type defined in a assembly containing entities which are about to be auto mapped. Very cool way for providing assembly name information. In the case of this blog post, Customer type is defined in BusinessLayer asembly, so this line would provide that information to fluent nhibernate auto mapping logic.
Then there’s a Where method which purpose is to define what types of a given assembly are to be mapped. In a sense it defines filter constraint criteria for auto mapping logic. In the case of this blog post, filter criteria is set to something like “all non abstract types implementing the IEntity which are defined in CustomerConfiguration namespace” . Any type not matching those rules wouldn’t be included in auto mapping process.
Once I’ve defined “what”, I start defining “how” by defining auto mapping conventions which are set of general settings defining how auto mapping logic should behave.
In the case of this blog post, conventions are defined like this:
- Every class would have identity property with name “ID” (If your property would be named “Id” there won’t be need for explicit definition because that is default setting Fluent Nhibernate uses)
- Database table name should be plural form of the class entity name (example: class Customer –> table Customers)
- Primary key column name would consist of type name and “ID” suffix (example: PK of Customer table would be named CustomerID)
- Foreign key column name would consist of parent type name and ID suffix (example: FK of ReferencePeople table would be CustomerID)
- Every string class property would be by default mapped to 50 character length column
- Every One – To – Many mapping would have Cascade.All cascade setting by default
Defining exclusions from AutoPersistenceModel definition
Now when I defined default mapping rules, I need to define what needs to be excluded from that auto mapping
namespace NHConfigMappings
{
private static void UpdatePersistenceModelWithExclusions(AutoPersistenceModel persistenceModel)
{
persistenceModel
.ForTypesThatDeriveFrom<Customer>(c => c.IgnoreProperty(p => p.CustomerAddress))
.ForTypesThatDeriveFrom<ReferencePerson>(c => c.IgnoreProperty(p => p.LastName));
}
...
}
As we can see here I’ve defined next exclusions:
- Cutomer.CustomerAddress property shouldn’t be auto mapped (because that would be Component and not One-To-Many type of mapping)
- ReferencePerson.LastName property shouldn’t be auto mapped (LastName property wouldn’t be mapped to LastName column)
Adding manual mapping definition to AutoPersistenceModel
For all of the non mapped and excluded exceptional entities which we still need to map to database entities, Fluent Nhibernate defines a way of adding manual mapping definitions to auto map defined auto persistence model
Here’s the code sample:
namespace NHConfigMappings
{
...
private static void UpdatePersistenceModelWithManualMappingInformations(AutoPersistenceModel persistenceModel)
{
// adding manual mapping to auto mapped persistence model
// 1. column level exceptions
persistenceModel.FindMapping<ReferencePerson>().Map(p => p.LastName, "SurName");// 2. components definition
persistenceModel.FindMapping<Customer>()
.Component<Address> (
x => x.CustomerAddress,
m =>
{
m.Map(x => x.Street).WithLengthOf(100);
m.Map(x => x.PostalCode).WithLengthOf(6);
m.Map(x => x.Town).WithLengthOf(30);
m.Map(x => x.Country).WithLengthOf(50);
});
}
...
}
UpdatePersistenceModelWithManualMappingInformations method updates persistance model like this:
- In auto persistence model definition find mapping for ReferencePerson entity and add mapping of the LastName property (to be mapped to SurName property)
- In auto persistence model definition find mapping for Customer entity and add component mapping for CustomerAddress property as defined in code sample
Checking the xml configuration files
Let’s take a quick peek at how configuration files generated from AutoPersistenceModel would look like
CustomerConfiguration.Customer.xml
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" assembly="CustomerConfiguration" namespace="CustomerConfiguration">
<class name="ReferencePerson" table="ReferencePeople" xmlns="urn:nhibernate-mapping-2.2">
<id name="ID" column="ReferencePersonID" type="Guid">
<generator class="guid.comb" />
</id>
<property name="LastName" column="Surname" length="50" type="String">
<column name="Surname" />
</property>
<property name="FirstName" column="FirstName" length="50" type="String">
<column name="FirstName" />
</property>
</class>
</hibernate-mapping>
CustomerConfiguration.ReferencePerson.xml
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping namespace="CustomerConfiguration" assembly="CustomerConfiguration" default-lazy="true" xmlns="urn:nhibernate-mapping-2.2">
<class name="ReferencePerson" xmlns="urn:nhibernate-mapping-2.2" table="ReferencePeople">
<property name="LastName" type="String" length="50" column="Surname">
<column name="Surname" />
</property>
</class>
</hibernate-mapping>
Now imagine you have hundreds of tables and entities and think about how much time and effort Fluent Nhibernate auto mapping functionality saves. Neat isn’t it?
Testing the AutoPersistenceModel based auto mappings
For the end of the blog post there’s only one thing left and that is to run the same test I wrote for Using NHibernate without configuration files post and to show that auto mapping works like it was working with manual class map definition
Here’s test fixture code…
namespace NHConfigMappings.Test
{
using System.Collections.Generic;
using CustomerConfiguration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NHibernate;[TestClass]
public class MappingsTest
{
private static ISessionFactory _sessionFactory;[ClassInitialize]
public static void FixtureInit(TestContext testContext)
{
_sessionFactory = new NHibernateBootstrapper().InitSessionFactory();
}[TestMethod]
public void ReferencePerson_Create_ShouldCreateRowInDb()
{
var customer = new Customer
{
Name = "John Doe",
CustomerNumber = "12345",
CustomerAddress = new Address
{
Street = "1st Mayson Street",
PostalCode = "01754",
Town = "Maynard",
Country = "USA"
},
References = new List
{
new ReferencePerson
{
FirstName = "Nikola",
LastName = "Malovic"
}
}
};ISession session = _sessionFactory.OpenSession();
session.Save(customer);
session.Flush();session.Evict(customer);
var customerDB= session.Get<Customer>(customer.ID);
Assert.IsTrue( customerDB.ID == customer.ID && customerDB.Name == customer.Name
&& customerDB.CustomerAddress.Street == "1st Mayson Street"
&& customerDB.References[0].FirstName == "Nikola");}
}
}
The main difference between tests in previous blog post and this one is that we don’t have in fixture init explicit session factory initialization. Instead, there’s only call to NHIbernateBootstrapper class InitSessionFactory method which I’ve already presented in this blog post. Test method is completely the same as the one from previous post. So it is the result of test run
Conclusions
- NHIbernate rock!
- Fluent NHibernate Auto mapping functionality rock!
There are a lot of blog posts about auto mapping functionality you might want to check out:
- http://ayende.com/Blog/archive/2008/12/11/fluent-nhibernate.aspx
- http://www.chrisvandesteeg.nl/2008/12/02/fluent-nhibernates-autopersistencemodel-i-love-it/
- http://www.pnpguidance.net/Post/AutoPersistenceModelFluentNHibernateORMapper.aspx
- http://marekblotny.blogspot.com/2008/12/fluent-nhibernate-conventions-and.html
Fluent NHibernate – NHibernate without configuration files
NHibernate is great, (no doubt about it) but every time I was supposed to work with it, the fact that I had to manually type in all those xml configuration entries was something I really didn’t like at all.
The most important complains I personally have on NHibernate configuration files are:
- It is error prone
- Errors in configuration file can be hard to trace
- It is not refactoring friendly
- It is not C#, it is XML
I believe that the most important reason why NHibernate is not more widely adopted by general DEV population is exactly the “Java XML configuration” PIA feeling you have while working with it.
Great news for all of us from that group: NHibernate is possible to be used WITHOUT configuration files!
Who, what and where?
Jeremy Miller coded initial bits of the Fluent NHibernate project and then James Gregory with couple of guys more bring the project to Google code and they started finalizing it. OSS rules!
So, if you go to http://code.google.com/p/fluent-nhibernate/ you would see names of other project members together with the simple code illustrating the goal fluent nhibernate project tries to achieve.
As with the most OSS projects, to get the source code of FNH, download it from Subversion trunk located at http://fluent-nhibernate.googlecode.com/svn/trunk/
Solution file consist of couple of projects:
- LIb solution folder contains DLL you would be using in your application.
- Test project containing a bunch of unit tests which you can use as starting point to get detail understanding on how the things works.
- Quick start project which highlights most important concepts you need to start using NHibernate
Note: Project is initially built with NHibernate 2.0 which collides with Linq For NHibernate (using NHibernate 2.1) so I updated FNH project references to use 2.1 too
Fluent NHibernate in action
Solution project structure
In this blog post, I will use the same example Jimmy Nilsson used in his Applying Domain-Driven Design and Patterns: With Examples in C# and .NET NHibernate chapter so you can compare outcome of my blog post sample it with how it looked in his book (with the configuration files in place).
Solution file of today’s example contains 3 projects:
- BusinessLayer (“Domain”)
Contains definitions of entities which we use in modeling business use cases.
Important to be mentioned here is that BusinessLayer project doesn’t have any reference to neither other projects of this solution nor the “3pty dlls” such is NHibernate.dll - NHConfigMappings (“Mapping project”)
Contains ORM mapping definitions which enables nhibernate to persist to relational DB domain entities - NHCongigMappings.Test
Contains test fixture illustrating how mappings should be consumed and how nhibernate engine could be initialized without any xml configuration files
(Source code used in today blog post can be download from here)
Domain project
As you can see, it is very simple sample where we have entity customer class containing “embedded” Address value object and referencing the list of reference persons customer contacted.
Same diagram given in code would look like this
using System;
using System.Collections.Generic;
namespace CustomerConfiguration
{
public class Customer
{
public virtual Guid Id { get; set; }
public virtual string CustomerNumber { get; set; }
public virtual string Name { get; set; }
public virtual Address CustomerAddress { get; set; }
public virtual IList ReferencePersons { get; set; }
}
}
Address type will look like this:
namespace CustomerConfiguration
{
public class Address
{
public virtual string Street { get; set; }
public virtual string PostalCode { get; set; }
public virtual string Town { get; set; }
public virtual string Country { get; set; }
}
}
And ReferencePerson type would look like this:
using System;
namespace CustomerConfiguration
{
public class ReferencePerson
{
public virtual Guid Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string SurName { get; set; }
}
}
As you can see from the code above, NHibernate allows us fully persistent ignorant POCO software development: no special attributes, no special base class or interface…
Mapping project
Once we have domain logic defined, we need to provide information on how NHibernate should map our classes with appropriate DB entities: tables and columns.
For my example DB would look like this:
As you can see, although in my code I have separate Address class I don’t have it in DB. Instead I have it embedded in Customer table as last 4 columns. Also, table names in DB are in plural form while names of classes are in singular form.
Another small difference here is that in ReferencePerson class has a LastName property while DB has column SurName.
Mapping ReferencePerson
I won’t throw in here example of how that would look if I would use XML configuration file, because the whole point is to forget that ASAP
(In case you want to see it, check it out here)
In order to define NHibernate mapping, in FNH you need to create a mapping class for each one of entities (which is something Ayende don’t get).
That mapping class should inherit from ClassMap<T> class in order to get access to FHN members providing programmatic access over configuration settings
using CustomerConfiguration;
using FluentNHibernate.Mapping;
namespace NHConfigMappings
{
public class ReferencePersonMap : ClassMap<ReferencePerson>
{
public ReferencePersonMap()
{
TableName = “ReferencePersons”;
Id(x => x.Id).GeneratedBy.GuidComb()
.WithUnsavedValue(“00000000-0000-0000-0000-000000000000”);
Map(x => x.FirstName).WithLengthOf(50).CanNotBeNull();
Map(x => x.LastName,”SurName”).WithLengthOf(50).CanNotBeNull();
}
}
}
Main advantage of fluent interface is that it produces code with good readability, which I believe we can see from code snippet above.
In a class constructor, I am defining:
- What is the name of data table where the class will be persisted. In my example table name and class name differs so I had to define it here, but I think it is good practice to define it always, even they are implicitly the same by the default
- Which class property should be used as Identity Field populating table PK. In example I took I am using ReferenceMap.Id property where NHibernate generate its value using GuidComb value as performance effective type of GUID values. At the end I defined how unsaved value is looking like so NHibernate would be able to deduct how the class should be persisted (insert or update)
- That the FirstName property should be mapped to the column with the same name where the column length is 50 characters and null values are not allowed
- That the LastName property should be mapped to the column named “SurName” with the maximum length of 50 characters without null values being allowed
In my opinion main advantages here are that the configuration code is human readable and refactoring friendly (if I ever do changes on ReferencePerson class mapping file will be broken so we have “type safe” configuration settings)
Mapping Customer
Customer class mapping definition is stored in CustomerMap (implementing the ClassMap<Customer> class looking something like this
using CustomerConfiguration;
using FluentNHibernate.Mapping;
namespace NHConfigMappings
{
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
TableName = “Customers”;
Id(x => x.Id).GeneratedBy.GuidComb()
.WithUnsavedValue”00000000-0000-0000-0000-000000000000”);
Map(x => x.Name).WithLengthOf(50);
Map(x => x.CustomerNumber).WithLengthOf(50);
HasMany<ReferencePerson>(x => x.ReferencePersons)
.Access.AsProperty()
.AsBag().WithKeyColumn("CustomerId")
.Cascade.All();
Component<Address>(x => x.CustomerAddress,
m =>
{
m.Map(x => x.Street).WithLengthOf(100);
m.Map(x => x.PostalCode).WithLengthOf(6);
m.Map(x => x.Town).WithLengthOf(30);
m.Map(x => x.Country).WithLengthOf(50);
});
}
}
}
In a class constructor, I am defining:
- The name of table to which this class map
- Customer.Id as primary key containing guid value
- Customer.Name is mapped to the Name nvarchar(50) column
- Customer.CustomerNumber is mapped to the CustomerNumber nvarchar(50) column
- Customer class contains collection of ReferencePerson instances stored in Customer.ReferencePersons property
which should be mapped in separate table (AsBag()) where role of FK will be performed by ReferencePerson.CustomerIdand with cascading of events (Insert of Customer will result with Insert of ReferencePerson etc)
- Customer contains property CustomerAddress of type Address as embed value where
- Address.Street is nvarchar(100) column
- Address.PostalCode is nvarchar(6) column
- Address.Town is nvarchar(30) column
- Address.Country is nvarchar(50) column
Once again, take a look at the class above. I have just described something which looks like typical use case we face in real world with something which (IMHO) has very high readability and it is easy to be written
Unit testing fluent nhibernate mappings
In order to present how those mappings should be used I wrote unit test project which will present:
- how this mappings are to be used
- how to configure nhibernate itself without the need for hibernate.cfg.xml file
For the purpose of this test I choose MS Test just for kicks (although I am mostly using MBUnit )
How to initialize nhibernate without hibernate.cfg.xml
Due to the fact that initializing nhibernate engine is slow, I am initializing it once per text fixture and in test fixture of this example nhibernate initialization routine in case of fluent nhibernate is a 5 step procedure:
- Initialize type implementing IPersistenceConfigurer (MSSqlConfiguration, SQLLiteConfiguration, PostgreSQLConfiguration are currently supported)
- use instance of that type (in my example instance of MSSqlConfiguration) to preset properties of NHibernate.Configuration instance
- create instance of FluentHibernate.PersistenceModel type
- use that instance to load the assembly containing mappings
- use that instance to inject mappings to nhibernate configuration instance
At the end of configuration sequence I have operational NHibernate configuration instance which I use to create session factory which I then store as a class field.
Once I have that SessionFactory field in place, each one of the test methods just uses it to create a session needed.
Let’s take a look at how this initialization routine could look in code
private static ISessionFactory _sessionFactory;
[ClassInitialize]
public static void FixtureInit(TestContext testContext)
{
// initialize persistance configurer
IPersistenceConfigurer persistenceConfigurer =
MsSqlConfiguration
.MsSql2005
.ConnectionString.Is(
“Data Source=.SQL2008;Initial Catalog=NHibernateBlog;"
+ "Integrated Security=True”)
.ShowSql();
// initialize nhibernate with persistance configurer properties
Configuration cfg = persistenceConfigurer
.ConfigureProperties(new Configuration());
// add mappings definition to nhibernate configuration
var persistenceModel = new PersistenceModel();
persistenceModel.addMappingsFromAssembly
(Assembly.Load(“NHConfigMappings”));
persistenceModel.Configure(cfg);
// set session factory field which is to be used in tests
_sessionFactory = cfg.BuildSessionFactory();
}
I think code above is simple enough (thanks to FNH) that it doesn’t need any extra explanations about its concrete implementation.
Nhibernate unit test method
Now when we have that session factory up and going, we would make only a simple test where we will create a new customer and try to store it in DB.
That test code could look like this:
[TestMethod]
public void ReferencePerson_Create_ShouldCreateRowInDb()
{
var customer = new Customer
{
Name = “John Doe”,
CustomerNumber = “12345”,
CustomerAddress = new Address
{
Street = “1st Mayson Street”,
PostalCode = “01754”,
Town = “Maynard”,
Country = “USA”
},
ReferencePersons = new List<ReferencePerson>
{
new ReferencePerson
{
FirstName = “Nikola”,
LastName = “Malovic”
}
}
};
ISession session = _sessionFactory.OpenSession();
Guid id=(Guid)session.Save(customer);
session.Flush();
session.Evict(customer);
var customerDB= session.Get<Customer>(id);
Assert.IsTrue( customerDB.Id == customer.Id && customerDB.Name == customer.Name
&& customerDB.CustomerAddress.Street == “1st Mayson Street”
&& customerDB.ReferencePersons[0].FirstName == “Nikola”);
}
At the beginning of the test method I create a new customer instance with CustomerAddress data and single ReferencePerson instance in ReferencePersons.
Then I use the sessionFactory created in test fixture set up, and create a session which then I use to persist customer instance. As a result of that persistence method call I am getting customer identity value used as PK value in DB.At the end of that persistence code I just flush the session in order to commit the changes.
Now when (hopefully) our customer is saved I need to test that and the usual way of testing save is to try to load the data from DB. That’s why I remove the customer instance from NHibernate Identity Map “cache” so I won’t get results from memory and then I am trying to retrieve data using the identity value I retrieved during persistence.
With the retrieved customer data I do just quick value check (in real world test this check would look different).
Test will pass therefore if retrieved data will match the data of customer instance created in this test.
Running the test
Once I run the test, I got successful test
And fast look at the DB shows that data are persisted
Test passed!
Conclusion
Purpose of this blog post was to present a way of using NHibernate different then the standard xml configuration approach most of people use right now working with NHibernate.
I hope you can see for yourself that it is VERY possible to use NHibernate without a single configuration file on very DEV friendly and intuitive way.
The example I presented here is just tip of the iceberg so I strongly encourage you to sync Fluent NHibernate source code and play with quick start and test projects.
Here are also some links you can check out too:
Happy Hibernating!
Model View Presenter (MVP) – Tips from trenches (TFT) – Working with HttpContext (Part 2)
Intro
This is part 2 of blog post series where I am presenting solutions I came up with to some common problems developers are facing implementing the MVP pattern in real world applications.
Previously on tips from trenches:
Today’s hurdle: Using HttpContext without System.Web
(Source code used in today’s example can be downloaded from here)
One of the principles I really feel strong about can be formulated like this:”Presenter is not allowed to reference System.Web assembly at all”.
Main reason why I feel so strong about that, is based on the fact that once referenced System.Web enables developers in your team to use types from that assembly (HttpContext, Session, Query, Cache etc) and we all know what PITA those types can be when testing Presenters.
Here’s very simple example I’ll use in today’s post:
Imagine you have a presenter which based on value of some query parameter is performing some redirecting or updating UI elements.
The easiest way (referencing the System.Web into presenter) will enable very easy implementation of required functionality but testing that code will require things like creating fake web context which IMHO is good sign of of important web test smell.
Luckily, there’s a solution
Model View Presenter pattern combined with Adapter design pattern offers easy and effective way of tackling this problem and this post is showing how to do that.
Adapter design pattern
This pattern is one of patterns I recently rediscovered as maybe one of the most useful patterns in every day programing. The pattern itself is not very sexy, because it is very simple. It’s purpose is to handle the cases
whenever we need to adapt the interface of one component to the interface we need.
Canonical example mostly used in explaining the pattern is the case of US and European power adapters. I am sure I am not the only one European who found himself shocked by the fact that power outlets in USA are totally different then the European one. In other words, European power sockets are wider and round while US are narrow and flat. Luckily, there’s Ebay where one can buy himself an adapter compatible with USA power outlets with entry holes compatible to European standards. That’s how you charge your laptop using original cable adapted to custom power outlet.
Adapter design pattern is exactly the same thing.
As we can see on above diagram, when client calls a Target object he would get instance of Adapter inheriting from Target which will delegate to SpecificRequest method of of Adaptee object all of the calls for Request() method (Adaptee object is containing instance of Adapter).
In other words, Adapter “implements via delegation” to Adaptee.
Building the TDD friendly HttpContext
Implementation of TDD friendly HttpContext will be based on couple of steps:
- building System.Web agnostic interface which would:
- perform the role of Facade by hiding most of the the members not important for MVP
- perform a role of a service contract which would be used by IoC container where custom HttpContext service will be need
- building special collection type which would enable us transparent intercepting interface members access
- building HttpContext service adapter which would implement the interface by delegating all of the calls to interface members to System.Web.HttpContext
- registering service into IoC container
Defining IHttpContextService
As previously mentioned, first step in implementing the TDD friendly http context is defining the feature list I am expecting to use in my Presenters. Based on some of my current experiences, that interface might look like this:
You can see from the interface definition to the left that (IMHO) important http context members are:
- Redirect(url) method – When presenter andor controller are responsible for driving navigation (more about controller in upcoming post)
- QueryString property – read only name-value collection property which contains collection of string pairs representing url parameter name and value
- User property - IPrincipal type doesn’t require usage of System.Web and defines a lot of useful things for implementing presenters
- ContextItems - read only property of custom name value collection type (more about that in second) which contains collection of string pairs representing name of httpcontext item and value that item carries
- Session – read only property of custom collection type containing string pairs representing application session variable entries
Key point here is that none of the members is not returning types from System.Web and that there are no Response, Request etc members. Only a small subset of really needed things defined in “easy to mock” way.
One thing Web Client Software Factory failed
While we speak about interface definition I would like to mention here a thing I’ve been disappointed seeing how it is been implemented there.
WCSF has IHttpContextLocatorService implemented like this (taken from reflector)
public interface IHttpContextLocatorService
{
// Methods
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IHttpContext GetCurrentContext();
}
and that IHttpContext interface look like this (part of)
public interface IHttpContext
{
// Methods
HttpApplicationState Application { get; }
HttpApplication ApplicationInstance { get; set; }
Cache Cache { get; }
HttpContext Context { get; }
ProfileBase Profile { get; }
HttpRequest Request { get; }
HttpResponse Response { get; }
}
As you can see by the fact that interface has members of types defined in System.Web, in order to use IHttpContextLocatorService I am still required to use System.Web. In other words, to get url query parameter I would still have to use System.Web.HttpRequest.
I might be missing something pretty big here, but IMHO there is no sense at all in how P&P team implemented this service. Testing pain I felt using WCSF related to this made me thinking about better solutions and this post is result of that
HookableNameValueCollection
Now when you saw interface definition and heard where from inspiration for this post came, let’s talk about the custom collection I used in interface while defining type of Session and ContextItems properties.
Design goal behind the decision for creating this collection is to provide the same simple feeling working with http context adapter as the one we are used to it while using the real HttpContext.
Here are some simple examples of what behavior I wanted to get:
- var x=httpContextService.Session[“SOME_KEY”]
- httpContextService.Session[“SOME_KEY”] =”123”;
- httpContextService.Session.Add(“SOME_KEY”,123);
- httpContextService.Session.Remove(“SOME_KEY”);
And here is what I was trying to avoid:
- var x= httpContextService.GetSessionValue(“SOME_KEY”)
- httpContextService.UpdateSessionItemValue(“SOME_KEY”,”123”)
- httpContextService.RemoveSessionItem(“SOME_KEY”)
One way to do that is to play again with Adapter pattern and transform HttpSessionState to IDictionary based adapter class and use that adapter type, but that would be solution specific only to this problem and (if there is an option) I always try to solve problem with reusable solutions. The way I have picked for this blog post is simply to create custom name value collection type where I am going to override Add/Remove/Set methods and raise appropriate events informing listeners that certain activity occurred.
Something like this:
Here’s the same diagram given through plain old c# code
namespace Vuscode.Framework.Abstractions
{
using System;
using System.Collections.Specialized;public class HookableNameValueCollection : NameValueCollection
{
public EventHandler<HookItemChangedEventArgs> ItemAdded;
public EventHandler<HookItemChangedEventArgs> ItemSet;
public EventHandler<HookItemRemovedEventArgs> ItemRemoved;public override void Add(string name, string value)
{
base.Add(name, value);
if (ItemAdded != null)
ItemAdded(this, new HookItemChangedEventArgs(name, value));
}public override void Set(string name, string value)
{
base.Set(name, value);
if (ItemSet != null)
ItemSet(this, new HookItemChangedEventArgs(name, value));
}public override void Remove(string name)
{
base.Remove(name);
if (ItemRemoved != null)
ItemRemoved(this, new HookItemRemovedEventArgs(name));
}
}
}
Building HttpContext service adapter
Once we have IHttpContextService and HookableNameValueCollection implemented, implementing httpcontext adapter is very simple implementation of the context interface.
Due to the fact that we would have to reference System.Web in order to adapt certain properties, I will create new component called Framework.Adapters and put the adapter class implementation there.
Implementation in general would look like this:
- Redirect method, QueryString collection property and User property would just delegate their calls to HttpContext.Current instance
- HttpContextServiceAdapter class subscribe to ContextItems and Session add/update/set events and performs appropriate calls to HttpContext.Current.Session and HttpContext.Current.Items
Let’s take a peek at how this implementation looks like in the C# code …
#regionusing System.Collections.Specialized;
using System.Security.Principal;
using System.Web;
using Vuscode.Framework.Abstractions;
using Vuscode.Framework.Abstractions.Web;#endregion
namespace Framework.Adapters.Web
{
public class HttpContextServiceAdapter : IHttpContextService
{
private readonly HookableNameValueCollection _context
= new HookableNameValueCollection();private readonly HookableNameValueCollection _session
= new HookableNameValueCollection();public HttpContextServiceAdapter()
{
InitSessionVariables();
InitContextVariables();
}#region IHttpContextService Members
public NameValueCollection QueryString
{
get { return HttpContext.Current.Request.QueryString; }
}public void Redirect(string url)
{
HttpContext.Current.Response.Redirect(url);
}public IPrincipal User
{
get { return HttpContext.Current.User; }
set { HttpContext.Current.User = value; }
}public HookableNameValueCollection Session
{
get { return _session; }
}public HookableNameValueCollection ContextItems
{
get { return _context; }
}#endregion
private void InitContextVariables()
{
if (HttpContext.Current.Items != null)
foreach (string itemsKey in HttpContext.Current.Items.Keys)
{
_context.Add(itemsKey,
HttpContext.Current.Items[itemsKey].ToString());
}_context.ItemAdded += ((sender, e)
=> HttpContext.Current.Items.Add(e.Name, e.Value));
_context.ItemSet += ((sender, e)
=> HttpContext.Current.Items[e.Name] = e.Value);
_context.ItemRemoved += ((sender, e)
=> HttpContext.Current.Items.Remove(e.Name));
}private void InitSessionVariables()
{
if (HttpContext.Current.Session != null)
foreach (string sessionKey in HttpContext.Current.Session.Keys)
{
_session.Add(sessionKey,
HttpContext.Current.Session[sessionKey].ToString());
}_session.ItemAdded += ((sender, e)
=> HttpContext.Current.Session.Add(e.Name, e.Value));
_session.ItemSet += ((sender, e)
=> HttpContext.Current.Session[e.Name] = e.Value);
_session.ItemRemoved += ((sender, e)
=> HttpContext.Current.Session.Remove(e.Name));
}
}
}
Key points:
- Constructor calls two methods:
- InitContextVariables – which iterates through all of the current Httpcontext.Current.Items and populate with their values custom context collection. After that, there’s code which implements event handlers for events published from context custom collection by using the lambda expressions. That’s how when ItemAdded event would be raised it would result with _httpContext.Items.Add method execution
- InitSessionVariables – same story here. Code first populate custom session collection with the entries already stored in session and then hooks up custom events with appropriate HttpContext Session methods
- Redirect method just delegates to _httpContext.Response.Redirect() method
- User property delegates implementation to _httpContext.User
- QueryString delegates implementation to _httpContext.Request.QueryString
IoC container context service registration
Now when we have service contract (IHttpContextService) and service (HttpContextServiceAdapter), the only thing left to be done is registering them into IoC container so presenters can use them in decoupled manner.
Doing that is very simple… First we add a reference to Framework.Adapters to web application project in order to get access to HttpContextServiceAdapter class. Then we create a simple class called BootStrapper.cs into web application root folder looking something like this
using Framework.Adapters.Web;
using Vuscode.Framework;
using Vuscode.Framework.Abstractions.Web;namespace Vuscode.Web.WebSite
{
public class Bootstrapper
{
public static void Init()
{
ServiceLocator.Register
<IHttpContextService, HttpContextServiceAdapter>();
}
}
}
At the end we just add call to Bootstrapper Init method into Application_Start event handler of global.asx so our IoC container would be populated at the beginning of web application life cycle.
Solution in action
Now when infrastructure is in place, implementing HttpContext related logic in presenter is very trivial
using Vuscode.Framework;
using Vuscode.Framework.Abstractions.Web;
using Vuscode.Framework.ModelViewPresenter;namespace Presenters
{
public class DefaultViewPresenter : Presenter
{
private readonly IHttpContextService _httpContextService;#region .ctors
public DefaultViewPresenter()
: this(ServiceLocator.Retrieve<IHttpContextservice>()){ }internal DefaultViewPresenter(IHttpContextService httpContextService)
{
_httpContextService = httpContextService;
}
#endregionpublic void SomeMethod()
{
string urlParam = _httpContextService.QueryString[“param”];
if (!string.IsNullOrEmpty(urlParam))
View.Parameter =urlParam;
if (urlParam == “nikola”)
_httpContextService.Redirect(“vuscode.com”);
}
}
}
At the beginning of the class we have standard poor man dependency injection combined with service locator thing.
(In case you are not familiar with what I just said go and check one of my Design For Testability (DFT) posts)
After we would inject the http context service it’s usage is exactly the same as it would be usage based on HttpContext.Current (which was one of the design goal) so everyone in your team should be able to start using it immediately
Unit testing HttpContext related presenter code
The test og SomeMethod given above can be now written before the SomeMethod implementation and it doesn’t require any Web reference.
Here is the fragment of the test illustrating how simple now is to test the HttpContext related things in Presenters (complete test fixture code can be found in code sample archive attached at the beginning of this post)
[TestMethod]
public void SomeMethod_InCaseOfNikolaParamValue_WouldRedirectToVuscode()
{
using (_mockRepository.Record())
{
// setting up the stage
SetupResult.For(_mockedHttpContextService.QueryString)
.Return(new NameValueCollection() { { “param”, “nikola” } });// defining expected behavior
_mockedHttpContextService.Expect(x => x.Redirect(“vuscode.com”));
}
using (_mockRepository.Playback())
{
var presenter = new DefaultViewPresenter
(_mockedHttpContextService) {View = _mockedView};
presenter.SomeMethod();
}
}
As you can see it from code above, to get url needed for test set up all one need to do is to set QueryString property of mocked IHttpContextService to contain desired URL parameters.
Then I define expected behavior using new Rhino Mock 3.5 syntax for void methods where I said that I expect that redirection to www.vuscode.com would occur.
Once the recording is over, in playback part I inject the mocked http context service and mocked view and call SomeMethod.
Ain’ that piece of cake?
What’s next?
Today I showed how to implement TDD friendly http context and introduced new infrastructure component Framework.Adapters.
My next blog post would introduce the role of Application controller in MVP (as a ported solution from WCSF)
‘till then…




