RSS 2.0
# Wednesday, January 20, 2010

Since I started using Git a few months ago, and particularly GitHub since last September, my life have been good in DVCS land.

I used to be a Subversion user and I was happy*, maybe because I didn’t know anything better. Of course I heard all the cool kids (specially in the Ruby world) talking about Git and bragging about it, but I was being loyal to my old pal SVN.

But this was slowing me down and I wasn’t aware of it. I’m not sure what make me install msysgit for the first time. After struggling a little bit at the beginning and wrapping my head around the concepts and the commands I noticed that my flow started to change.

This change was good. Was more Agile. Doing small commits for little changes of code seems natural since the speed of this commits was almost instantaneous (remember the commits happens in your own machine). I’m talking of commits been done almost at the line of code level.

Change this line, run the test, commit. Write another test. Make it fail. Write some code. Make it pass. Commit. Refactor. Run test. Commit. Keep going.

Once It was time to push those changes to the master a single command push every change + every comment at blasting speed.

Since them I started using Mercurial as well and the experience was very similar. In the case of Mercurial I just use TortoiseHg but I stick with the command line for Git for most of my operations and I’m glad of that decision.

I wasn’t planning on writing this post today but I just happen to grab the code for edgecase Ruby Koans from GitHub and it took me all of 1 minute to do everything. Here is the flow:

Open Console2 and launch the Git bash. Type the following sequence of commands.

Welcome to Git (version 1.6.4-preview20090730)
Run 'git help git' to display the help index.
Run 'git help <command>' to display help for specific commands.
Hernan@HERNAN-STUDIO /c/Development
$ cd Code/Ruby/Koans_unresolved/
Hernan@HERNAN-STUDIO /c/Development/Code/Ruby/Koans_unresolved
$ git pull git://github.com/edgecase/ruby_koans.git
fatal: Not a git repository (or any of the parent directories): .gi
t
Hernan@HERNAN-STUDIO /c/Development/Code/Ruby/Koans_unresolved
$ git init
Initialized empty Git repository in c:/Development/Code/Ruby/Koans_
unresolved/.git/
Hernan@HERNAN-STUDIO /c/Development/Code/Ruby/Koans_unresolved (mas
ter)
$ git help
Hernan@HERNAN-STUDIO /c/Development/Code/Ruby/Koans_unresolved (mas
ter)
$ git pull git://github.com/edgecase/ruby_koans.git
remote: Counting objects: 294, done.
remote: Compressing objects: 100% (286/286), done.
remote: Total 294 (delta 184), reused 0 (delta 0)Receiving objects:  44% (130/29Receiving objects:  45% (133/294)
Receiving objects: 100% (294/294), 51.84 KiB, done.
Resolving deltas: 100% (184/184), done.
From git://github.com/edgecase/ruby_koans
 * branch            HEAD       -> FETCH_HEAD
Hernan@HERNAN-STUDIO /c/Development/Code/Ruby/Koans_unresolved (master)
$

 

Notice that I had to type help because I didn’t remember if I had to add a remote or I was able to do a pull right away (I removed the help output from the console output fro brevity).

Of course the Ruby Koans are just a bunch of very simple text files but the whole process took me less than 2 minutes. I think that is not just because Git is faster but also using the command line for this type of task tends to be a lot faster than using a Gui tool.

If you haven’t try it yet go ahead and take the plunge. Go distributed, even if you work alone, you want regret it.

*I’m still using Subversion at work, looking forward to have the time to switch but we are dealing with some time sensitive projects so I don’t want to mess around with that.

kick it on DotNetKicks.com Wednesday, January 20, 2010 12:42:31 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Continuous Integration | Methodology | Programming | Tools
# Monday, January 18, 2010

In case you don’t know what it is. Codemash is a conference put together by volunteers. It has been running for four years now. The conference happens at the Kalahari Resorts and Convention Center that has reportedly the biggest indoor water park in North America. That is in Sandusky, Ohio.

Organization

I only have one world for it, spectacular. You come in and once you register you get your welcome package, a tag and a marker to write down your name, nickname, handler or however you want to be identified. (I saw one tag that only have a big E in it. And that is cool). A lot of attendees (me included) choose to add their twitter handle. If you think about it, at the end of the day a lot of us talk to each other or read each other on twitter so that makes sense. After that your only problem in the world is try to get to as many sessions or open spaces as possible.

Content

Multiple technologies and practices are been represented at Codemash. Ruby, Java and JVM languages, .NET and CLR/DLR languages, Python, Iron*, C. Functional and OO. SOLID, BDD, TDD, Lean, Leadership, Coaching, Patterns. Iphone, Rails, WebForms, Silverlight, WPF, Tapestry and more development platforms, etc. And if you can’t find what you want, you still have the open spaces, so go ahead and create your own conference. I bet people will join you.

There is content at the Beginner, Intermediate and Advanced levels. I could like to see a few more 400 level talks but if you think that the idea of the conference is to try to get you out of your comfort zone that may not be very wise. Let me explain.

The idea is to try to go to talks that are not about the same technologies that you use every day. For example I choose to attend some F#, Ruby, Python and Clojure talks. My level of familiarity varies so I was able to follow and take some good information from the sessions since they were at the intermediate/beginner level.

Sessions and open spaces I enjoyed.

The keynotes by Mary Poppendieck’s The Five Habits of Succesful Lean Development and Andy Hunt’s The Mother of all Bugs

Some of the sessions/Open spaces: Presentation Patterns. What makes ruby different. Open space about FubuMVC. NoSQL: Death to relational DB’s. Introduction to Cucumber. Testing ASP.NET applications using Ruby. Being and evil genius with F#. 0-60 with Fluent NHibernate. Building webapps with Compojure. IronPython with ASP.NET.

The venue

Perfect. I think that the venue is part of the magic that make this Conference so special. Imagine that you are in this African themed hotel, where people wearing sandals and T-shirts around you will be checking their emails or updating their twitter timeline from their smart phones. Imagine going to a water park after the last session of the day, or just go and play mini golf with your son. That makes for a very relaxed vibe and you feel it and see it at the conference.

The staff at the hotel is great, friendly and professional and all interaction (from the moment I made my reservation on the phone) was very pleasant.

The food

Ok. This is something I’m really surprised. You pay $175 for the 2 days of conference + $150 for the extra Precompiler day. That’s a grand total of $325  for a 3 day conference. So, you may expect to have some scarcity on the food supply, specially when you consider that you have breakfast and lunch all of three days and dinner on one of the days.

Well, let me tell you something. There was not such thing. The food was good and plentiful. Actually It was fantastic. I went to conferences where I paid $2000 for the same number of days and all I got was a wrap or a sandwich that was prepared 12 hours before.

On top of that there was coffee and pops (coke and sprite cans) available during the day to keep you going.

What I will change

Nothing from the conference, maybe extended to 3+1 days?

My recommendations for new attendants.

If you have a family take them with you, specially if you have kids. My only mistake (and seems to be a common theme among first timers) was to go along. The organization even has a KidsMash going on where the kids can play and be ask geeks as their parents when they are tired of the water park.

Try to study the list of sessions in advance but relax and make sure you scan the Open spaces regularly and keep an eye on that twitter timeline. If you are not getting the most of the session you are in move to another one, just try not to disrupt

And like in most conferences take a power cord (a long one if possible) with you.

I’m already impatiently waiting for next year Codemash. I can only say a big thank you to all the people that works to make such a great experienced for all of us.

kick it on DotNetKicks.com Monday, January 18, 2010 11:16:28 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [1] - Trackback
General
# Friday, January 01, 2010

Kazi Manzur Rashid has a post about registering Areas dynamically after the registration of other routes and the problems this has since the order the routes are registered is very important. Go read his post and come back for a possible solution to the problem.

Ok, based on his post I decided to try to implement exactly what he is looking for. After poking around with reflector and brushing up my Reflection skills I came up with a first implementation that does the trick.

  1:     public static class RoutCollectionExtension
  2:     {
  3:         public static RouteCollection AddArea(this RouteCollection routes, string routeName, Route newRoute)
  4:         {
  5:             var fieldInfo =  routes.GetType()
  6:                 .GetField("_namedMap", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  7: 
  8:             var dict = fieldInfo.GetValue(routes);
  9:             dict.GetType()
 10:                 .GetMethod("Add", BindingFlags.Public | BindingFlags.Instance)
 11:                 .Invoke(dict,new object[]{routeName,newRoute});
 12: 
 13:             fieldInfo.SetValue(routes,dict);
 14: 
 15:             routes.GetType()
 16:                 .GetMethod("InsertItem", BindingFlags.NonPublic | BindingFlags.Instance)
 17:                 .Invoke(routes, new object[] { 0, newRoute });
 18: 
 19:             return routes;
 20:         }
 21:     }

After posted this solution as a comment on Kazi’s post I decided to polish this a little more and to actually provide a similar API as the MapRoute extension from the MVC framework. The idea is to provide a set of InsertRoute and InsertRouteAfter.

So for the InsertRoute, this is the final code:

  1:     public static class RoutCollectionExtension
  2:     {
  3:         public static void InsertRoute(this RouteCollection routes, int index, string routeName, Route newRoute)
  4:         {
  5:             var fieldInfo =  routes.GetType()
  6:                 .GetField("_namedMap", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  7: 
  8:             var dict = fieldInfo.GetValue(routes);
  9:             dict.GetType()
 10:                 .GetMethod("Add", BindingFlags.Public | BindingFlags.Instance)
 11:                 .Invoke(dict,new object[]{routeName,newRoute});
 12: 
 13:             fieldInfo.SetValue(routes,dict);
 14: 
 15:             routes.GetType()
 16:                 .GetMethod("InsertItem", BindingFlags.NonPublic | BindingFlags.Instance)
 17:                 .Invoke(routes, new object[] { index, newRoute });
 18:         }
 19: 
 20: 
 21:         public static Route InsertRoute(this RouteCollection routes, int index, string name, string url)
 22:         {
 23:             return routes.InsertRoute(index, name, url, null, null);
 24:         }
 25: 
 26:         public static Route InsertRoute(this RouteCollection routes, int index, string name, string url, object defaults)
 27:         {
 28:             return routes.InsertRoute(index, name, url, defaults, null);
 29:         }
 30: 
 31:         public static Route InsertRoute(this RouteCollection routes, int index, string name, string url, string[] namespaces)
 32:         {
 33:             return routes.InsertRoute(index, name, url, null, null, namespaces);
 34:         }
 35: 

36: public static Route InsertRoute(this RouteCollection routes, int index, string name, string url,

object defaults, object constraints)

 37:         {
 38:             return routes.InsertRoute(index, name, url, defaults, constraints, null);
 39:         }
 40: 

41: public static Route InsertRoute(this RouteCollection routes, int index, string name, string url,

object defaults, string[] namespaces)

 42:         {
 43:             return routes.InsertRoute(index, name, url, defaults, null, namespaces);
 44:         }
 45: 

46: public static Route InsertRoute(this RouteCollection routes, int index, string name, string url, object defaults,

object constraints, string[] namespaces)

 47:         {
 48:             if (routes == null)
 49:             {
 50:                 throw new ArgumentNullException("routes");
 51:             }
 52:             if (url == null)
 53:             {
 54:                 throw new ArgumentNullException("url");
 55:             }
 56:             var item = new Route(url, new MvcRouteHandler())
 57:                              {
 58:                                  Defaults = new RouteValueDictionary(defaults),
 59:                                  Constraints = new RouteValueDictionary(constraints),
 60:                                  DataTokens = new RouteValueDictionary()
 61:                              };
 62:             if ((namespaces != null) && (namespaces.Length > 0))
 63:             {
 64:                 item.DataTokens["Namespaces"] = namespaces;
 65:             }
 66:             routes.InsertRoute(index, name, item);
 67:             return item;
 68:         }
 69:     }

The problem with this is that you probably don’t know the index of the routes and those index will change with each route that get’s registered. So InsertRouteAfter is better since we can insert a route after another route by name. The code is very simple, I won’t display all the overloads just the actual implementation.

  1:         public static void InsertRouteAfter(this RouteCollection routes, string nameOfExistingRoute, string nameOfRouteToInsert, Route newRoute)
  2:         {
  3:             var fieldInfo = routes.GetType()
  4:                 .GetField("_namedMap", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  5: 
  6:             var dict = fieldInfo.GetValue(routes);
  7:             dict.GetType()
  8:                 .GetMethod("Add", BindingFlags.Public | BindingFlags.Instance)
  9:                 .Invoke(dict, new object[] { nameOfRouteToInsert, newRoute });
 10: 
 11:             var existingRoute = dict.GetType()
 12:                 .GetProperty("Item")
 13:                 .GetValue(dict, new[] {nameOfExistingRoute});
 14: 
 15:             fieldInfo.SetValue(routes, dict);
 16: 
 17:             var index = routes.GetType()
 18:                 .GetMethod("IndexOf", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
 19:                 .Invoke(routes, new[] {existingRoute});
 20: 
 21:             index = (int) index + 1;
 22: 
 23:             routes.GetType()
 24:                 .GetMethod("InsertItem", BindingFlags.NonPublic | BindingFlags.Instance)
 25:                 .Invoke(routes, new[] { index, newRoute });
 26:         }
Warning!!!

If you decide to use this code make sure that you have tests in place since we are relying in things like the name of a internal field that can be changed without affecting the public API so this extensions are fragile from that point of view. Besides that, reflection is slow, but since route registration should happens only once per application I’m not worry about that part.

 

Shout it
kick it on DotNetKicks.com Friday, January 01, 2010 10:47:18 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Programming
# Saturday, December 26, 2009

When the Codemash guys announced their API I decided to create an app using it. I wasn’t sure what to do at first but It was pretty obvious anyway. Some kind of scheduling tool.

It took me some time to have the time to start and them to finish it. I finally was able to deploy this last night and today I add another feature to considered completed based on my initial goal.

You can visit the tool here: http://mysessioncalendar.com/ 

What it does?

The tool has three tabs one for each conference day and a third for the pre compiler. Each tab has columns (representing the rooms where the sessions take place, just noticed I don’t have the room on top) and them the sessions are displayed below ordered by time.

The idea is that you can select the sessions you are interested in. The tool does not make any judgement calls and if you want to select two sessions in the same time slot is up to you. Once you mark all the sessions just click the “Save Schedule” button on top and a modal dialog will display with a link to open (in a new window) a list with the selected sessions.

This time the sessions are ordered in three columns: One for each day and the sessions for each day are ordered by time.

The page has the AddThis widget that allow you to twit, email, print, add to favourites, show them in facebook and more. Another cool option is to export them as iCal
, this way you can add them to your google calendar and other tools supporting this format.

How was done.

The site have been implemented using ASP.NET MVC, jquery for all the JavaScript and the UI design using JQueryUI. Data is saved as xml so no need to use databases. Originally I started using Castle.ActiveRecord since the data model is extremely simple, but is so simple that the use of a db was overkill. The total time to have the site done was maybe 24 man hours divided in several coding sessions of no more than 3 hours at a time.

The use a a widget like AddThis make implementing the sharing functionality a 15 minutes deal.

Conclusion.

There are some things that can be better like font sizes (thanks Ahmed for the report). Originally I wanted to have a better interface with drag and drop or double click in a session to select, but decided to go with a simpler implementation and get this out of my computer and into the wild.

kick it on DotNetKicks.com Saturday, December 26, 2009 10:10:11 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [1] - Trackback
General
# Sunday, November 22, 2009

Some time ago I wrote a first impressions about ASP.NET MVC in Action from Manning. It was after downloading an reading a few chapters available via the Manning early access program (MEAP). The book was written by Jeffrey Palermo, Ben Scheirman and Jimmy Bogard.

A month ago or so I finally got my print copy and I started reading it right away. Let me put it simple, this book is fantastic. If you are planning to do any development with the framework you need to have it in your book shelves.

The content span over just 352 pages and it covers pretty much every single aspect of the framework. It follows a very clear path explaining how the pieces fit together. I think that It can be useful for both the experienced and the novice programmer.

One of the remarkable aspects of the book is the constant focus on testability and customization of the different pieces of the framework to help you reduce friction and improve the design of your application.

I also felt that the authors took a very pragmatic approach while exposing users to different options on implementing web applications with the framework.

I can see the book as having 3 parts. The first 6 chapters explain and show how to use and extend the framework. Chapters 7 to 10, explore more complex scenarios, like complex sites, use of AJAX, how to leverage existing asp.net features and hosting/deploying your final app.

The last part is a compendium of Best practices, Recipes and an study or other two MVC frameworks, Monorails and Ruby on Rails.

kick it on DotNetKicks.com Sunday, November 22, 2009 5:25:43 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [2] - Trackback
Books
# Monday, November 16, 2009

I try to be pragmatic in my approach to development and one of the things that change the most are the tools I use to deliver software. There are several reasons why I change tools so often.

  1. The evolution of the software I write call for new or different tools.
  2. Search for efficiency and eliminate pain points.
  3. I change my approach to software development and new methodologies need new tools.
  4. I just love to try new stuff :-)

In this post I want to concentrate in the tools used to manage projects and builds. Until recently my favoured tools in this context consisted of NAnt, CC.Net/Hudson and Subversion.

For bug tracking I used the bug tracker in Google code for my OSS projects integrated to TortoiseSVN or BugTracker.Net. (Note: At work we use FogBugz and we are very happy with it.)

Subversion was the first to go.

Subversion is a great VCS but I usually have two problems with it. Speed and problems with complex merges.

When I work alone, merges are not an issue of course, but speed still is. At the same time more and more people seems to be switching to DVCS (Distributed or Decentralized) systems like Git or Mercurial. After taking a quick look at GitHub and follow their tutorials I was able to move some of my projects there in a few hours. (Most of the time spent on reading and learning from other people mistakes).

Git is fast, Fast, FAST! The whole idea of local commits and clone repositories is fantastic and they really help me with my workflow in the sense that I can do one or two changes, commit, one or two more, commit, find a bug, revert change, finish a story, push to GitHub.

To manage Git I’m using a combination of command line and graphic interface using Git gui. So far I haven’t feel the need to use/install TortoiseGit.

I still have some projects hosted in google code and I’m using Subversion with them, I’m thinking on switch them over to GitHub once I start working on them again.

Nant followed it.

I don’t have a problem with XML so the fact that Nant is XML based does not bothers me, really. But I also like the power of a good scripting language to manage repetitive tasks. I decided to move away from Nant and try to adopt some of the newest build systems.

I took a look at psake and them I read “How a net developer learned ruby and rake to build net apps in windows” by Derrick Bailey and that convinced me to take the plunge.

My knowledge of Ruby is extremely rudimentary but I even with that handicap I was able to have a Rake build script up and running in less than 90 minutes. This script cleans the build target, create the Package folder, builds the VS solution, run Nunit test on two dll's, generate the NUnit report as an xml file, and run the migrations from Migrator.Net (that last part is not working yet, I will need to take a closer look at Migrator.Net command line args).

The most useful resource on Derik's post was Laribee's OMG Rake!. Laribee’s sample code and a few queries to Google was all I need. (No, I did not copy and paste ALL Laribee’s code, just use it as a reference)

Agile Zen or project management made easy.

I got a free account on Agile Zen the first week after they went live. I remember creating the account, playing around on the Board and leaving the site. My thoughts at the moment were something like. This is actually cool. Very nice design. Good usability. I should give it a proper test drive with some real project.

Of course, I never came back until last Friday. While working in a few features for Pronghorn I decided that it was time I stop spiking and started to write proper user stories to drive the framework. I remembered Agile Zen and went back.

The site looks great and there are some improvements since that last time I saw it.

What really amazed me is how intuitive the whole process is. There is no waste generated by using this tool. Creating stories is 1 click. Editing stories, another one. Color coding two clicks. Double click in a field to edit them, etc. Very easy, very intuitive. There is even a bar at the bottom with hints that I decided to hide and I didn’t miss it.

The site is very responsive and the only thing I miss is integration with a VCS system. They have a very simple API for paying accounts, but in the docs it looks like is read only, so no hooks in there (If anybody knows otherwise, please leave a comment).

I will keep using it for another week or so before making a final decision but so far everything indicates that I will be upgrading the account to a paying one pretty soon. (The free account only allows for one project and one developers, what is more than fair.)

Tying it up all together with CI.

As I mentioned before my main experience have been using CruiseControl.Net and Hudson as the CI servers. I installed TeamCity a long time ago to give it a try but I never use it. My first choice was to look for some hosted solution. After searching I only found a few and non of them worked with .Net (at least not at the moment).

I was going to go back once more with Hudson but I wasn’t able to connect to the Hudson site to download the code. (Their site is up now). So I decided to take a new look at JetBrain’s TeamCity. At the moment of this writing they are running the EAP for version 5.

I wanted to install it and use my newly crafted Rake build script with the .Net project and have my test report integrated in the dashboard.

First I got the msi from the daily builds for version 5.00. Double click on it to install the server and the agent and after a few minutes and two (three?) questions, the home page of the serve shows up in the browser.

Creating the first project and associated build profile was a breeze. I just followed along the instructions in the screen. A few times when I wasn’t sure what a given label meant, I made use of the contextual help.

I did have an issue but it was my fault when setting some relative path to the build file and the build target, for running test and creating the Package folder.

From downloading the installer to having the project building successfully took me between 10 to 15 minutes.

Conclusion.

This new setup makes me more productive since I have better tools that save me time in different areas like. Setting things up, working around their idiosyncrasies, configuration heavy or too verbose a language.

While this is a combination that works for me, yours may be completely different. The important part is to have tools that feel this roles and make sure that they are really working with and for you and not the other way around.

kick it on DotNetKicks.com Monday, November 16, 2009 12:26:55 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [1] - Trackback
Continuous Integration | Methodology | Programming | Testing | Tools
# Tuesday, November 10, 2009

The NoSql movement is  gaining more and more inertia. A year or two ago I took a look at CouchDb but this time I wanted to try MongoDB. I have been hearing a lot of nice things about MongoDB, mostly about how simple is to query it and how fast is. So I decided that it was time to actually take it for a spin.

A quick search point me to this odetocode post that was a great starting point to have Mongo running in my dev machine using the defaults and the Driver for C#. So, go and read K. Scott Allen’s post if you want to follow along with the code in the rest of this post.

Detour (some background on NoSql and MongoDB):

If you already know about this you can skip all this paragraph.

The so called NoSql movement is based on the notion that using RDBMS may not be the right choice in some cases. They propose using alternative databases, like key-value pair storages and document databases. To perform operations on the data some make use of Map-Reduce, others like MongoDB use a query mechanism that resembles Sql. One of the most attractive features of this db’s is the ability to easily run clusters and do data sharding. Most of them support both features without a lot of fuss, or that I heard.

MongoDB is a document based db, that stores the information as Binary Json.

End of detour.

What’s a document?

A document is not the equivalent to a Row. A document can be seen as a key-value pair collection of objects. It’s actually a complete object Graph, persisted as Json. Documents are organized into Collections.

Now, to be usable in C# we need to have some mapping from the Document object to our object graph. We could use the Document directly but will be like going back to use DataTables, not very pretty.

  1: var movieName = movie["Name"].ToString();
  2: var actors = JsonConvert.DeserializeObject<Dictionary<int,string>>(movie["Actors"].ToString());

The simple way to go from Json to an object should be to pass the load of a document to a JsonDeserializer like Json.Net and just get the object back, like this:

  1: var movie = JsonConvert.DeserializeObject<Movie>(document.ToString());

But while trying to do so I got an error in the id of the document. Looking at the paymoad of the document the Id looks like this:

  1: "_id": ObjectId("4eebf0006829c72c1d000000")

The problem is in the ObjectId function. But do not despair, there is an alternative.

From a document to a fully usable object graph.

The alternative is not pretty but works and is easy to implement. Just pass the document to the root of your object graph, an access the underlying collection via the objects properties. Let’s see how this can look like. (Note: Yes there are some hardcoded strings in there that should be removed. I’m also never closing the connection to the Db, when I probably should).

  1: using System;
  2: using System.Collections.Generic;
  3: using Newtonsoft.Json;
  4: using MongoDB.Driver;
  5: 
  6: public class Repository
  7: {
  8:     private Database _db;
  9: 
 10:     public Database Db()
 11:     {
 12:         if(_db != null) return _db;
 13:         var server = new Mongo();
 14:         server.Connect();
 15:         _db = server.getDB("DynamicProgrammer");
 16:         return _db;
 17:     }
 18: 
 19:     public void Insert(Document document, string collectionName)
 20:     {
 21:         var collection = Db().GetCollection(collectionName);
 22:         collection.Insert(document);
 23:     }
 24: 
 25:     public IEnumerable<TDocument> getListOf<TDocument>(string whereClause, string fromCollection) where TDocument : IMongoEntity
 26:     {
 27:         var docs = Db().GetCollection(fromCollection)
 28:             .Find(whereClause).Documents;     
 29:         return docsToCollection<TDocument>(docs);
 30: 
 31:     }
 32: 
 33:     private IEnumerable<TDocument> docsToCollection<TDocument>(IEnumerable<Document> documents) where TDocument : IMongoEntity
 34:     {
 35:         var list = new List<TDocument>();
 36:         var settings = new JsonSerializerSettings();
 37: 
 38:         foreach (var document in documents)
 39:         {
 40:             var docType = Activator.CreateInstance<TDocument>();
 41:             docType.InternalDocument = document;
 42:             list.Add(docType);
 43:         }
 44:         return list;
 45:     }
 46: 
 47: }
 48: 

IMongoEntity is a simple interface to force our entities to expose the Doc property.

  1: public interface IMongoEntity
  2: {
  3:     Document InternalDocument { get; set; }
  4: }
  5: 

And our Movie Entity will look like:

  1: public class Movie : IMongoEntity
  2: {
  3:     public string Name
  4:     {
  5:         get { return InternalDocument["Name"].ToString(); }
  6:         set { InternalDocument["Name"] = value; }
  7:     }
  8: 
  9:     public int ProductionYear
 10:     {
 11:         get { return (int)InternalDocument["Year"]; }
 12:         set { InternalDocument["Year"] = value; }
 13:     }
 14: 
 15:     public Dictionary<int, string> Actors
 16:     {
 17:         get { return JsonConvert.DeserializeObject<Dictionary<int, string>>(InternalDocument["Actors"].ToString()); }
 18:         set { InternalDocument["Actors"] = value; }
 19:     }
 20: 
 21:     public Document InternalDocument { get; set; }
 22: }

Notice I’m using JsonConverter to return a complex type, we should probably encapsulate that functionality in some kind of base class, maybe convert IMongoEntity into an abstract class that provides some basic utilities.

I will try to dig deeper into MongoDB, seems to be really suited to a Domain first approach. I wasn’t able to have anything but the most simple queries working, so I will have to take a closer look at the syntax.

kick it on DotNetKicks.com Tuesday, November 10, 2009 12:04:54 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [4] - Trackback
Programming | Tools
# Sunday, November 08, 2009
kick it on DotNetKicks.com Sunday, November 08, 2009 12:43:56 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback

Add The Dynamic Programmer Mippin widget
Navigation
Archive
<January 2010>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
What I'm reading
Shelfari: Book reviews on your book blog
About the author/Disclaimer
Hernan Garcia I have been a software developer for the last 16 years or so.
I was a journalist before and I still consider myself one.
Besides baseball, programming is my other big passion.

Me on twitter. @TheProgrammer
Certified Scrum Master
© Copyright 2010
Hernan Garcia
Sign In
Statistics
Total Posts: 197
This Year: 15
This Month: 1
This Week: 0
Comments: 70
Themes
Pick a theme:
All Content © 2010, Hernan Garcia