Probably you are aware of Edgecase Ruby Koans. In case you aren’t, let me introduce you to them. From Wikipedia, Koan: A kōan is fundamental part of the history and lore of Zen Buddhism. It consists of a story, dialogue, question, or statement whose meaning cannot be accessed by rational thinking, yet it may be accessible by intuition. A widely known kōan is "Two hands clap and there is a sound; what is the sound of one hand?" The Ruby Koans are a set of failing test that you need to resolve. Of course the idea is not just to resolve the test as fast as you can but to read the code carefully and understand why it’s failing and them provide the solution. Once you download the code you just run the rake command inside the folder where the Koans have been downloaded and you will be presented with a failing test and a message in the screen that indicates what you need to do to fix the test. You should take as much time as needed to contemplate the solution and internalize the code, the syntax and the constructs that Ruby use. I went through them once and I’m planning on do it again in a day of two. The Koans cover some important aspect in the following areas: asserts, arrays, arrays assignments, blocks. Classes, open classes and class methods. Inheritance, hashes, exceptions and so much more, this is the complete list of files in the Koans folder: 17/01/2010 11:25 PM 2,024 about_arrays.rb
17/01/2010 11:29 PM 1,015 about_array_assignment.rb
17/01/2010 12:27 PM 942 about_asserts.rb
18/01/2010 11:51 PM 2,392 about_blocks.rb
21/01/2010 12:02 AM 3,873 about_classes.rb
21/01/2010 06:20 AM 3,820 about_class_methods.rb
18/01/2010 12:11 AM 2,320 about_control_statements.rb
22/12/2009 10:24 PM 1,436 about_dice_project.rb
18/01/2010 12:24 AM 1,374 about_exceptions.rb
22/12/2009 10:24 PM 317 about_extra_credit.rb
17/01/2010 11:35 PM 1,765 about_hashes.rb
21/01/2010 12:07 AM 1,652 about_inheritance.rb
18/01/2010 10:10 PM 2,441 about_iteration.rb
21/01/2010 06:39 AM 4,277 about_message_passing.rb
18/01/2010 12:02 AM 3,613 about_methods.rb
21/01/2010 12:10 AM 1,132 about_modules.rb
17/01/2010 08:08 PM 1,020 about_nil.rb
21/01/2010 12:03 AM 920 about_open_classes.rb
21/12/2009 04:38 PM 3,295 about_proxy_object_project.rb
19/01/2010 12:10 AM 2,657 about_sandwich_code.rb
21/01/2010 12:15 AM 1,870 about_scope.rb
20/01/2010 11:46 PM 1,843 about_scoring_project.rb
17/01/2010 11:51 PM 4,725 about_strings.rb
22/12/2009 10:24 PM 771 about_triangle_project.rb
22/12/2009 10:24 PM 486 about_triangle_project_2.rb
18/01/2010 12:12 AM 788 about_true_and_false.rb
22/12/2009 10:24 PM 1,111 array_test.rb
21/12/2009 04:38 PM 19 code_mash.rb
21/12/2009 04:38 PM 4,498 edgecase.rb
22/12/2009 10:24 PM 15 example_file.txt
22/12/2009 10:24 PM 156 first_test.rb
22/12/2009 10:24 PM 2,323 GREED_RULES.txt
21/01/2010 06:32 AM 895 path_to_enlightenment.rb
21/12/2009 04:38 PM 159 Rakefile
02/01/2010 10:19 PM 5,482 README.rdoc
22/12/2009 10:24 PM 70 test_helper.rb
18/01/2010 12:29 AM 821 triangle.rb
|
Open your favorite editor, launch the console and start running the Koans, just type rake and you will be presented with messages like this,after fixing it your awareness will “expand”.
Thinking AboutOpenClasses
test_as_defined_dogs_do_bark has expanded your awareness.
test_after_reopening_dogs_can_both_wag_and_bark has damaged your karma.
You have not yet reached enlightenment ...
<"HPPY"> expected but was
<"HAPPY">.
Please meditate on the following code:
./about_open_classes.rb:26:in `test_after_reopening_dogs_can_both_wag_and_bark'
path_to_enlightenment.rb:28
|
It’s very addictive, the only complain/suggestion I have is to provide some answer to some of the question in the code. May be in a separate show?
# THINK ABOUT IT:
#
# Is it better to use
# obj.nil?
# or
# obj == nil
# Why?
In the context of this article every time I mention Linq I’m actually talking about Linq To Objects. Although Linq has a very handy method on FirstOrDefault<T>. When applying this method to a collection you will get in return the First object of the default of T. This works great with numeric values in the sense that the default is not null. So you can do stuff like this without anything blowing up. 1: var list = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
2: var valueAsString = list.FirstOrDefault(l => l == 10).ToString();
3: Console.WriteLine(valueAsString);
The result will be “0”.
But what if you do this with a list of strings?
1: var listOfStrings = new List<string> { "h", "j", "k" };
2: var stringToUpper = listOfStrings.FirstOrDefault(l => l == "a").ToUpper();
3: Console.WriteLine(stringToUpper);
You will get this:
System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=FirstOrNullObject
StackTrace:
at FirstOrNullObject.Program.Main(String[] args) in C:\Development\Code\DotNet\VS2010\DynamicProgrammer\FirstOrNullObject\FirstOrNullObject\Program.cs:line 21
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Why? The default of string is null.
A possible solution.
Sometimes you need to filter a list of objects and access one of the properties of the object right away. For that we can use the Null Object pattern, but how to tell Linq about it?
Linq is implemented as a set of extension methods on IEnumeration<T>, so let’s add another one!
1: public static T FirstOrNullObject<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T nullObject)
2: {
3: var val = enumerable.FirstOrDefault<T>(func);
4: if (val == null)
5: {
6: val = nullObject;
7: }
8: return val;
9: }
This is easy to understand, we apply the passed Func<T,bool> to FirstOrDefault if the result is null we return the passed nullObject.
For completion we also need to create on that can be used to get the first element of the collection without applying any filtering.
1: public static T FirstOrNullObject<T>(this IEnumerable<T> enumerable, T nullObject)
2: {
3: var val = enumerable.FirstOrDefault<T>();
4: if (val == null)
5: {
6: val = nullObject;
7: }
8: return val;
9: }
You get the most value of this methods when filtering collections of complex objects, like your domain objects. You have to be careful to use them when expecting a null object is ok, sometimes is not and a null value should be treated as an error or an exception, but in other cases is perfectly normal to get a null object as the default. You should understand that the null object is different from a default implementation of the object (like a new instance). Default objects may return some default values in their properties. For those scenarios I like to create another extension methods where you pass an instance of a new T.
1: public static T FirstOrNew<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T newObject)
2: {
3: return enumerable.FirstOrNullObject<T>(func, newObject);
4: }
5: public static T FirstOrNew<T>(this IEnumerable<T> enumerable, T newObject)
6: {
7: return enumerable.FirstOrNullObject<T>(newObject);
8: }
You may notice that the implementation is calling the methods we created before, the only difference is in the name of the methods and the parameters. But it’s important to be clear on what the methods will do.
Another approach is to use the same FirstOrDefault name for your new methods and you will end up with four methods, the two on Linq plus two implement by you with this signature.
1: public static T FirstOrDefault<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T defaultObject)
2: public static T FirstOrDefault<T>(this IEnumerable<T> enumerable, T defaultObject)
And who knows, maybe that is the best approach.
Technorati Tags: Linq, Null Object
I got a copy of the MEAP edition for ASP.NET MVC in Action. This is the book on the (new?) ASP.NET MVC framework written by Jeffrey Palermo, Ben Scheirman, and Jimmy Bogard. I have been looking forward to both the final release of the framework and the book. Palermo has been very involved in the MvcContrib project as well, and all the authors have been posting about the framework since the early releases. Yesterday I went over the first four chapters. So far so good. As always with any book, depending on the level of your knowledge in the subject, there are things that you could like to be deal with more in depth and other stuff that since you can skip over. The really good points for me is that they put some emphasis in working with an architecture that will scale in a complex web site. Even when the code examples may be based on a simple model, they don’t treat them as trivial and the focus put on showing the testing is very good. Specially this last few days (week) with the controversy created about SOLID principles and Tests is nice to see that a book about a framework that should allow us to improve our coding of .net applications is paying special attention to this details. I will keep reading and waiting for updates on the book, I’m specially high on my expectations for Chapter 13 - IronRuby, IronPython, and the DLR, that is not available yet.
In part 1 I talked about using the facade pattern or a wrapper to avoid dependencies to third party libraries. In the second part I talked about taking care of custom exceptions defined in those libraries and how to shield you client code from them. Today I want to talk about Attributes that those libraries may define and that may force you to use them. The problem here is that if you use them you will add a dependency to the original library, so any effort done to hide the use of that library will be lost. If the library is an open source project there is a solution and is change the code of the library. If not you should decide if there is no other alternative and in the worst case scenario live with the dependency. “Fixing” the problem when using Open source libraries. I had a situation while using Json.Net. I had a class and I wanted to mark two methods to be ignored by the serializer, to do so in Json.Net you need to use the JsonIgnoreAttribute. The problem is that I implemented a wrapper on top of Json.Net so non of my class hold a dependency to the library. This allow me to change the library used to do the actual parsing if I chose so without impacting my clients. Now, if I add the attribute to all the classes that I will eventually serialize the dependencies on Json.Net may well be all over my code base. The problem here is that the use of an attribute on this case is reasonable. My solution was to actually change the code and use the XmlIgnoreAttribute (from the .Net framework), but the problem is that if I get a new version of the library now I will have to go and change the code again. The other problem is that the attribute name is misleading for another developer, it does not communicate the real implications of using it. I think that a better approach (for all libraries) is to provide a default implementation but let the end user to change them, for example let him to inject attributes types to replace the defaults. In the above example, I could create my own SerializeIgnoreAttribute and inject it for a key IgnoreSerialization into Json.Net. The library may have an in memory dictionary or read this preferences for a configuration file (less desirable).
In a recent post I talked about isolating your code from third party libraries using the facade pattern. In the post I wrote about wrapping log4net (as an example) in your own logging class and define an interface for the log object that better reflects your domain. The main benefit of doing this is that your client code (the one that needs a logger) won’t have a dependency on an interface defined by an external library, given you the desired flexibility to change the library that implements the logger later on. All your client code will keep using your abstraction. But what happens if the external library defines it’s own exceptions? What if one of this exceptions may be thrown during usage and you want to catch it and do something to fix the problem? Let’s assume the 3rd party library is an html parser library that contains the following classes: ThirdParty.HtmlParser.HtmlElement ThirdParty.HtmlParser.Parser ThirdParty.HtmlParser.HtmlElements : IEnumerable<HtmlElement> ThirdParty.HtmlParser.MalFormedHtmlException : Exception
Notice the MalFormedHtmlException class, this is an exception that this library may throw. At this point just wrapping the library alone won’t help you. What you need to do is catch the exception in the wrapper library and raise you own exceptions.
This exceptions may have the same meaning but for sure the name will more closely reflects your domain.
Let’s create a simple wrapper that returns all images url’s in an HtmlDocument given an id:
public class HtmlParser{
public HtmlParser(Uri url){ //... }
public IEnumerable<string> GetImagesUrls(){ //... }
}
Now the problem is that GetImagesUrls needs to parse the document and at that moment the MalFormedHtmlException. Knowing this your client code will have to do something like this to protect the application from crashing.
public class ParserUI{
public void ShowImages(){
//Some code try{ parser.GetImagesUrls(); }catch(MalFormedHtmlException){ testLabel.Text = "Oops, the html document is not valid and can't be parsed." }catch(Exception e){ //More code }
}
}
A this moment our UI holds a reference to the original library to brake that dependency.
We need to modify the code for the wrapper and provide our own exception.
public class HtmlParser{ public HtmlParser(Uri url) { //... } public IEnumerable<string> GetImagesUrls() { try{ }catch(MalFormedHtmlException){ throw new HtmlMalFormedException() }catch(Exception) //.... } }
public class HtmlMalFormedException : Exception {
public HtmlMalFormedException() : base(@"The html for the document is not well formed html. Please use a tool like the w3c Validator to verify the document"){}
}
Now the client can be change as well
public class ParserUI{
public void ShowImages(){
//Some code try{ parser.GetImagesUrls(); }catch(HtmlMalFormedException htmlMalFormed){ testLabel.Text = htmlMalFormed.Mesage }catch(Exception e){ //More code }
}
}
Notice how you just removed any dependency to the original library, but you can also use the message from the exception to display to the end user. Since you know your domain, the message can be tailored in a way that explain what just happened and even provide alternative solutions on how to fix the problem.
Next time we will talk about attributes.
You can find this new ORM framework at http://code.msdn.microsoft.com/XGENOORM. Starting with it is fairly easy. Just add a reference on your project to the very small (32K) dll (only one!) and you can start playing with it. First impressions. My observations come from reading the documentation and not from using it. What I like. It uses the ActiveRecord pattern what I like personally prefer for simple applications. Since this claim to be a simple ORM this is acceptable. You should understand that this mean that your objects need to inherit from a base class that provides the CRUD operations. If you want to use just POCO’s without dependencies on your ORM this won’t be a good choice. This is an issue with the pattern though and not this particular ORM. Mapping is done using Attributes For Example if you create a new class Dog and you want to mapped into a table Animal you do this [Table(Name = “Animal”] public class Dog { [Column(Name = "Id")] public int Id {get; set;} [Column(Name = "Name")] public string Name {get; set;} }
One of the problems I found from my liked is the querying capabilities, no the lack of but the way they are implementing. You pass a Condition object to the Find method, but this object make use of strings, what it’s ugly and doesn’t work well with Refactoring tools like ReSharper.
If we want to find all dogs where the name starts with A we will do something like this.
var condition = New Condition("Name", "like", "A%");
Not only is using strings for the Column name but also for the operand of the condition. I would prefer a different notation, something like this:
var condition = New Condition<Dog>(d=>d.Name, Operand.Like, "A%");
At this point relationships are not supported they are promising this for the next release.
A nice feature is the Audit Attributes, this Attributes are used to mark some properties of your object to save data as modification dates, creation dates and user that changed the objects. All this is done automatically for you, what it’s a very nice idea.
In conclusion if you need something extremely simple and you don’t care about the relationships you may be able to use it. If you need something more mature using the same pattern I will stick with Castle ActiveRecord at this moment.
As a side note this doesn’t seem to be open source, so there may not be any support from the community, an strength of the Castle project
Besides programming against Interfaces and using Dependency Injection to reduce coupling, there is another practice that can/should be used when you consume an external library. That is provide a wrapper around the library or in other words the use of the Facade pattern. Why? Consider this example. using System; using System.Collections.Generic; using System.Text; using log4net.Core;
namespace HtmlHelpers { public class UnorderedList { private readonly ILogger _logger;
public UnorderedList(ILogger logger) { _logger = logger; }
public string Render(IEnumerable<string> collectionToPrint) { try { _logger.Log(collectionToPrint.GetType(),Level.Info,"Starting to render the list",null);
var list = new StringBuilder(); list.Append("<ul>");
foreach (var item in collectionToPrint) { list.AppendFormat("<li>{0}</li>", item); }
list.Append("</ul>");
_logger.Log(collectionToPrint.GetType(), Level.Info, "Finishing to render the list", null);
return list.ToString(); } catch (Exception e) { _logger.Log(collectionToPrint.GetType(),Level.Fatal,"Can't render the list",e); throw; } } } }
As you can see using the ILogger interface in the constructor give us the ability to pass any object that implements it, but take a look at the using statements.
using System; using System.Collections.Generic; using System.Text; using log4net.Core;
Yeah, Log4Net is there, so even when we are isolating ourselves from a dependency to the concrete implementation, we are still carrying a dependency to the assembly. Not only that but if we want to change our logging service we need to do it for some other logging service that implements the same interface.
As well you are having a dependency on the Level enumeration used in the signature of the Log method from the ILogger interface.
_logger.Log(collectionToPrint.GetType(),Level.Fatal,"Can't render the list",e);
While we are at this, take a look at that signature, you may want to do something simpler to use. So what will be the chance for another third party Logging library to implement this ILogger interface? Null of course.
The solution is the Facade pattern. We start defining our own interface for logging.
using System;
namespace FacadePattern { public interface ILogger { void LogException(Exception e); void LogException(string message, Exception e); void LogInfo(string message); } }
Notice how we create specific method for the levels we want to use, you may need other methods later on, but you can always implement them when you actually need them.
Now, we create a concrete implementation that uses Log4Net.
using System; using System.Diagnostics; using System.IO; using System.Reflection; using log4net; using log4net.Config;
namespace FacadePattern { public class Logger : ILogger { private readonly ILog _logger;
public Logger() { XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine( AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "log4net.config"))); MethodBase m = new StackTrace().GetFrame(1).GetMethod(); _logger = LogManager.GetLogger(string.Format("{0}.{1}", m.DeclaringType, m.Name)); }
public void LogException(Exception e) { _logger.Error(e.Message, e); } public void LogException(string message, Exception e) { _logger.Error(message, e); }
public void LogInfo(string message) { _logger.Info(message); } } }
Now our objects that need Logging can consume our own implementation and any dependency on Log4Net is removed. At this point we can use Dependency Injection to provide our concrete implementation of the logging class and we are free to change the library that does the actual logging anytime we want.
using System; using System.Collections.Generic; using System.Text; using FacadePattern;
namespace HtmlHelpers { public class UnorderedList { private readonly ILogger _logger; public UnorderedList(ILogger logger) { _logger = logger; }
public string Render(IEnumerable<string> collectionToPrint) { try { _logger.LogInfo("Starting to render the list");
var list = new StringBuilder(); list.Append("<ul>");
foreach (var item in collectionToPrint) { list.AppendFormat("<li>{0}</li>", item); }
list.Append("</ul>");
_logger.LogInfo("Finishing to render the list");
return list.ToString(); } catch (Exception e) { _logger.LogException("Can't render the list",e); throw; } } } }
Also notice how much more clean and readable is the log code.
We are living in very exiting times in the .Net world. Every time I look I find a new framework to do web development. I recently found FubuMVC. This framework is a bit different from Sharp Architecture or the Catharsis guidance since this one does not use ASP.NET MVC but is inspired by it. Fubu is an acronym which means "For us, by us." After using the Microsoft ASP.NET MVC Beta framework and disagreeing with some of the design choices made therein, several of us decided to try to bend it to our design choices using its extensibility points. Eventually we reached our goal, but we realized we had overrode or replaced large portions of the MVC framework. At this point, it was suggested that maybe we take it one step further and write our own MVC framework starting at the same layer where ASP.NET MVC begins. This is the realization of that suggestion. To be clear: This framework is NOT based on the ASP.NET MVC Framework at all. It is inspired by it, however. The project is very active at the moment with several daily commits almost every day, but there isn’t a lot of documentation. The wiki is practically empty. I guess at this point they are focusing on functionality. I downloaded the code and was able to do a build with no problems. You can build using VS or Rake. See this wiki article on how to start with Fubu. To use Rake you need to have Ruby installed on the machine to take advantage of their script. There is a batch file to install the Rake gem if you don’t have it, so just install Ruby and them start playing. Here is some of the output using Rake, notice that the build script runs the test as well, something we all know is a good practice, but not everybody does, doesn’t it? Taking a look at the Project Open the FubuMVC solution file inside the src folder. Run the Test projects, everything should be green, you should see 3 ignored cases.
Since I’m using windows XP in this machine I wasn’t able to properly run the AltOxite project since It doesn’t seem to work properly with Cassini and or IIS 5.1. UPDATE: This have been already fixed on the trunk, so update your checkout now.
I really like this framework, so far (looking and browsing the code) this is the one I like the best from an architectural point of view. It’s simple and powerful at the same time. Enforcing best practices (or what I think about us best practices) like separation of concerns. See in the example the controllers live in a separate assembly from the web project. (Sharp Architecture and Catharsis both take the same approach by the way). A few links to the project author’s blogs.
I was going to write a post about this but my thoughts are exactly the same as Fredrik Normen’s. For example, one thing that creeps me out is seen think like this in the Controller. 23 public ActionResult Index() 24 { 25 var repository = IocContainer.GetClassInstance<IRepository>(); 26 var members = repository.GetAll<Member>(); 27 ViewData["members"] = members; 28 return View(); 29 } Or even worse: 45 public ActionResult CreateMember() 46 { 47 var member = new Member(); 48 member.Hydrate(Request.Form); 49 50 if (member.Email == null) 51 { 52 ViewData.ModelState.AddModelError("Email", "Email can't be empty"); 53 } 54 //More code here 55 } I don’t think that the controller should ever touch the repository and of course it shouldn’t do any type of validation besides data entry from the view.
On December 2nd Sharp Architecture released version 0.9.114. Sharp Architecture is a project created by Billy McCafferty. It’s an architecture framework for web application that uses ASP.NET MVC, NH 2.0.1, NHibernate.Validator, Fluent NHibernate, and Castle Windsor. From their site: Pronounced "Sharp Architecture," this is a solid architectural foundation for rapidly building maintainable web applications leveraging the ASP.NET MVC framework with NHibernate. The overall goal of this is to allow developers to worry less about application "plumbing" and to spend most of their time on adding value for the client by focusing on the business logic and developing a rich user experience. - Focused on Domain Driven Design
- Loosely Coupled
- Preconfigured Infrastructure
- Open Ended Presentation
There is of course a strong focus on TDD as well. New on this version (from the change log) * A Visual Studio 2008 template project has been added under /TemplatesAndCodeGen to get your own S#arp Architecture project up and running quickly * Replaced Ninject with Castle Windsor * Added support for behavior driven unit testing * Unit tests now use an in-memory SQLite database for testing data access methods along with providing an integration verification mechanism to check mappings against a live database * This will likely be the last interim release before version 1.0 I think that the project templates and wizards are a big plus on this package. In the roadmap for version one this is what we can look for: * WCF integration * Hone CRUD capabilities * Support for multiple databases * Example of using a Unit of Work to encapsulate non-trivial controller logic * Scaffolding generators! There is a discussion group on Google groups to provide support and ask for help. Another thing that really impress me was the 34 pages Word document included with the release. It’s very detailed, from configuration to usage. There is a explanation for each of the Tiers in the architecture, a tutorial to develop with it that covers the TDD cycle and a set of best practices. The documentation is very detailed, specially on thing that may seem of minor importance as on how to configure the IDE to be consistent with the sample code!!! If you haven’t do so, go download it and play with it.
I will try to create a simple CMS framework on top of the ASP.Net MVC. This will be mostly an exercise, something that I feel I need to try to see how it works. Some of the goals: - The framework will be extensible but opinionated.
- The views need to be composite and the markup created by the designer should be very simple with minimum or no code at all.
- The framework needs to provide a centralize Exception handler mechanism.
- Multiple sites in one install.
- Partial views should use a common interface (IViewModule?) so we can provide a modular architecture.
- Easy to template by a designer, easy to skin by a designer.
- HTML and CSS standards compliance friendly.
- In line administration are fully backend integrated to the site.
- Testability is paramount, and the framework should come with a good set of unit test as part of the release.
- Been able to run the test from inside the framework, so install can diagnose problems.
I will be posting more about this and some code as soon as I have something put together.
InfoQ published some videos for sessions at Agile 2008.Agile 2008 was held here in Toronto two weeks ago and I participate as a volunteer. It was a great experience and the variety and quality of the talks was really good. From the videos at InfoQ I have to recommend the followings: We suck less is not enough! David Douglas and Robin Dymond talk about companies that don't fully commit to Agile or just adopt part of the methodologies, failing in the process and (maybe) hurting Agile. I still think that is possible to take some of the Agile practices and implement them with a great deal of success, without having to go all the way. I know that I'm not alone in this train of though but is interesting to see examples in the real world were this is not the case and the consequences of this. Something to have in mind. The Development of a New Car at Toyota Kenji Hiranabe sessions were a success. In this session he shares his experience meeting Nobuaki Katayama, Chief Engineer at Toyota and what he learned from it. With all the talking about lean that is going on you need to listen to it. A complete list of videos and publishing dates are available in the Agile 2008 section of the InfoQ site.
A few weeks ago Jeffrey Palermo published his notion of an Onion Architecture. The first time I saw it was during his MVC presentation at DevTeach Toronto and I really like it. As he mention in his posts this is not a revolutionary technique but mostly a way to clearly express good practices and patterns and a way to maximize decoupling in an intelligent way.I highly recommend that you go ahead and read the series, there is a lot of though put into this. Layers instead of tiers.In the past Agile 2008 a have the great pleasure to assist to Mario Cardinal presentation on Separation of Concerns.He mentions the use of “Layered Module” architecture style. What means design thinking about modules as unit of deployment and using IoC and DI between this layers but not internally in the same layer. He also make a good distinction about layers and tiers when he talks about this architecture.You can download his Powerpoint presentation from his website.Mario mentioned that he will doing a presentation or a workshop at DevTeach Montreal so if you are planning to go, make a note to participate.
Jeffrey Palermo gave a great presentation about the ASP.NET MVC framework. If you read my blog you know that MVC is kind of an obsession with me. The presentation used the codecampserver project that use the last drop of the code for the MVC and the last version of Palermo's MvcContrib as well.It was concise and covered the most important topics (at least from my point of view), it was fast paced and good fun. There was a very nice moment where he shows up how to use a controller to render different views. Sometimes return Json data amd sometimes return a web page. You can also see something similar at Iridescence. It was very interesting to see the architecture of codecamp, he uses a Layered onion architecture for the multi tier architecture, very interesting concept. I think that you may have used something like this but I never saw this graphical representation and makes a lot of sense. The most traditional representation doesn't work as well as this one. At least for this type of applications. I recommend that you download the slides for the presentation and take a look at it.One of the things I like the most is that he include the Test as a layer of the architecture. This is important because It make the tests first class artifacts on the solution and not an after though or something that can be considered as trivial. I almost forget, Palermo played some very cool music before and after the presentation. Palermo posted the material for this presentation on his blog.
I have been reading a lot about how this framework will better be used in brand new developments. I agree that you won't migrate an existing site to this framework if the existing site is working, but I'm worry that we are missing another opportunity to use this framework and that is leverage existing models an business logic. Most examples keep using LINQ TO SQL to generate the model from scratch and that may give the false impression that you need to generate the model that way. I will show how to use an existing model with the MVC, in this case a DooDads DAL. Notice that the only difference between this and my last post is that the project doesn't have any files under the model folder, I'm actually using those files to create the dll for the DAL. 
I just added a reference to the classes that I need to consume my model from. 
At this point all the controller classes will have access to my model. using System; using System.Web; using System.Web.Mvc; using LaTrompa.Dal; using MyGeneration.dOOdads;
namespace MvcDemo2.Controllers { public class MovieController : Controller {
[ControllerAction] public void List() { Movies movieList = new Movies(); movieList.LoadAll(); MovieViewData customViewData = new MovieViewData(); customViewData.MovieList = movieList; RenderView("List", customViewData); } }
public class MovieViewData { public Movies MovieList { get; set; } } } I think that this is a really cool application for the MVC framework, imagine how fast you can implement a web front end leveraging existing Model and Business objects, maybe used by a desktop app. And further on, this objects don't even need to connect to a MSSQL database, they can point to whatever db your layer support.
I have been using DooDads, a free, open source ORM architecture for a while now. I like that I can easily use it with any database structure, not matter how bad is it. When I come across such designs DooDads is the tool that allows me to create a layer of abstraction pretty fast into the application, that will later on allow me to make changes and refactor the database with minimal impact in the upper layers. I'm also a sucker for the MVC pattern and I downloaded as soon as was avalable, I have been playing around with it and one of the things I wanted to do was test it's extensibility using my favorite ORM tool. Setting things up.So I fired up VS and create a new MVC application. I create a db with one table and I call it Movies. I open MyGeneration and generate the code for the business entity for the table and the Stored Procedures that the object will use. 

The Model.Then I added the code into the Model folder in the solution opened in Visual Studio 2008 and create the concrete class for the Movie object, Doodads generated code use abstract classes. 
I like to separated the generated code from my implementation using two different folders but you don't need to do so if you don't want. I think that is easier to maintain this way. My next step was to modify the menu to create a Movies item, so I opened the master page and added the following line. <ul> <li><a runat="server" href="~/">Home</a></li> <li><%= Html.ActionLink("Movies", "List", "Movie") %></li> <li><%= Html.ActionLink("About Us", "About", "Home") %></li> </ul> You will need to add the connection string as and appSetting in the web.config for Doodads to pick it up. The key should be dbConnection. <appsettings> <add value="Data Source=SERVERNAME;Initial Catalog=DATABASE;Integrated Security=True" key="dbConnection"></add> </appsettings> The Controller.Them I added a reference to MyGeneration.Doodads.dll and them create a new Controller class named MovieController 
The code for this class is very simple. I added the using statement for the namespace of my Model classes and I create a custom ViewData object using the new simpler properties. Declaring the type of the property will give me a strongly typed ViewData in the View. using System; using System.Web; using System.Web.Mvc; using LaTrompa.Dal;
namespace MvcApplication1.Controllers { public class MovieController : Controller { [ControllerAction] public void List() { Movies movieSelection = new Movies(); movieSelection.LoadAll(); MoviesViewData customViewData = new MoviesViewData(); customViewData.MovieList = movieSelection;
RenderView("Movie", customViewData); } }
public class MoviesViewData { public Movies MovieList { get; set; } } } The View. I created a folder called Movie under View and inside a Movie page (I made this page of the MVC Content page type to use the same master page). 

I added a using for the controllers namespace and set the type of the ViewPage<T> object to my custom viewdata object. using System; using System.Web; using System.Web.Mvc; using MvcApplication1.Controllers;
namespace MvcApplication1.Views.Home { public partial class Movies : ViewPage<moviesviewdata> {
} } I them opened the aspx page and added the following. <%while (!ViewData.MovieList.EOF) { %> <h2><%= ViewData.MovieList.Title%></h2> <p><%=ViewData.MovieList.Description%></p> <%= Html.ActionLink(ViewData.MovieList.Category, "List", "Category")%> <% ViewData.MovieList.MoveNext(); } %> And that is all you need, in a future article I will consume the Model as a precompiled assembly and I will demostrate how to use a webservice as a model. 
The CTP release of the Microsoft MVC framework is available with the ASP.NET 3.5 extensions. Scott Hanselman has a post on this release so does Scott Gu, don't miss the 40 minutes video on Hanselman's, it's a quick introduction to the MVC framework and is worthy even if you already saw the original presentation at Alt.Net that started it all. I didn't download it yet, since the machines I have at home at this moment don't have VS 2008 but I will do first thing tomorrow morning. There is an extra download for the MVC framework with html helpers and data support (not sure what is in it). I can't be more exited about it.
In this second part we look at the factory methods to handle the different request and the formatters classes. The Factory.The use of a factory allow us to easily extend this framework with minimun coding. using System; using System.Web;
namespace LaTrompa.Services { public class ServiceHandlerFactory { /// <summary> /// Creates a ServiceHandler appropiate for the call /// </summary> /// <param name="up">A UriProcessor object with the data from the call</param> /// <returns>A class that implements IServiceable</returns> public static IServiceable Create(UriProcessor up) { return (IServiceable)Activator.CreateInstance(Type.GetType("LaTrompa.Services." + up.ReturnFormat + "ServiceHandler")); } } } Some base classes.We need to encapsulate some code, so we apply the DRY principle, that code will reside in two base classes. The first class is used by our formatter classes, they need to format different type of objects so they need to call a class that knows how to process the call for that given object, get the object, modify it according to the parameters and commands and them returned to the formatter class that will format it and do the response. using System; using System.Web;
namespace LaTrompa.Services { public class FormatServiceHandler { protected object GetRequestedObject(HttpContext context) { UriProcessor up = new UriProcessor(context.Request.Url); IServiceRequestHandler service = (IServiceRequestHandler)Activator.CreateInstance(Type.GetType("LaTrompa.Service." + up.ObjectType + "ServiceHandler")); return service.GetRequestedObject(up); } } } The second object, is one of our objects handlers, some scheleton code at this moment. This objects implement IServiceRequestHandler. using System; using System.Collections.Specialized; using System.Web; using MyGeneration.dOOdads;
namespace LaTrompa.Services { public class DataServiceHandler : IServiceRequestHandler { private BusinessEntity _dataObject;
protected void LoadDataObject(string objectName) { this._dataObject = (BusinessEntity)Activator.CreateInstance(Type.GetType("LaTrompa.DAL." + objectName, true, true)); }
private object List(NameValueCollection qs) { return null; } private object Delete(NameValueCollection qs) { return null; } private object Insert(NameValueCollection qs) { return null; } private object Update(NameValueCollection qs) { return null; } private object GetColumns() { //this._dataObject. return null; }
#region IServiceRequestHandler Members
public object GetRequestedObject(UriProcessor up) { this.LoadDataObject(up.ObjectName);
switch (up.Command.ToUpper()) { case "LIST": this.List(up.Qs); break; case "DELETE": this.Delete(up.Qs); break; case "UPDATE": this.Update(up.Qs); break; case "INSERT": this.Insert(up.Qs); break; case "GETCOLUMNS": this.GetColumns(); break; } return null; }
#endregion } } The Formatter classusing System; using System.Web;
namespace LaTrompa.Services { public class JsonServiceHandler : FormatServiceHandler, IServiceable { public void Process(HttpContext context) { object requested = base.GetRequestedObject(context); //TODO: Implementation } } }
If you haven't look at it, take a look at the Subsonic project, is really cool and can generate a ORM infrastructure faster than any other framework I tried out there and it also provides a cool HTTPHandler to expose those objects. The only problem is that your database have to follow some minor conventions and sometimes you need to work with legacy databases where those conventions where not follow. A solution is to use the DooDads architecture and My Generation as the code generating tool. Doodads was always open source and now My Generation is open source as well. I even modify the BussinessEntity class on the architecture to fit my needs in some projects and work around some unorthodox database architectural decisions I found. Once you have your doodads objects for all the tables and views that you want to expose you need to create the HttpHandlers to expose those objects. This are some of the things I needed: - Pure REST
- Not so pure REST
- Multiple response formats (ex: Json, Xml, Csv)
- Being able to expose new databases object in the future without coding, just generate the object and a change in the url should make the object available.
- The API should document itself (ex: the end user should be able to ask for available properties (columns) on a object)
- Being able to expose not just databases objects but other type of objects in the future.
URL Format and how to read them.I wanted very easy to read urls, so I came with this scheme. http://domain/Web/ObjectType/ObjectName/command.format?params Where: domain: Do I need to explain this? (ex: blog.latrompa.com) web: The subfolder where your api will reside (ex: services) ObjectType: The type of object to expose (ex: data) ObjectName: The name of the object (ex: Article) command: The command to execute on the object (this is only for non true REST, true REST use the HTTP VERB) (ex: list) format: The extention inidicates the format of the response (ex: json) params: The querystring with parameters to modify the response. A url to request the Data for all Articles Created after October first 2007 will look like this. http://blog.latrompa.com/Services/Data/Article/list.json?created_more=10/01/2007 Notice the parameters created is the name of a field in the Article table and the _more indicates what operand to use in the where clause. It took this idea from the HttpHandler implementation on Subsonic Architecture:Interfaces.using System; using System.Web;
namespace LaTrompa.Services { public interface IServiceable { void Process(HttpContext context); } } using System;
namespace LaTrompa.Services { public interface IServiceRequestHandler { object GetRequestedObject(UriProcessor up); } } Utilities.I create this class to map a uri into an object for easy manipulation, the uri is what will tell us wich object to load and how to process it. using System; using System.Collections.Specialized; using System.Web;
namespace LaTrompa.Services { public class UriProcessor { #region Properties
private string _web = string.Empty; /// <summary> /// Gets the Web use to call the service /// </summary> public string Web { get { return _web; } }
private string _protocol = string.Empty; /// <summary> /// Gets the protocol used to call the service /// </summary> public string Protocol { get { return _protocol; } }
private string _domain = string.Empty; /// <summary> /// Gets the domain used to call the service /// </summary> public string Domain { get { return _domain; } }
private string _returnFormat = string.Empty; /// <summary> /// Gets the return format for the service /// </summary> public string ReturnFormat { get { return _returnFormat; } }
private string _objectType = string.Empty; /// <summary> /// Gets the type of object requested /// </summary> public string ObjectType { get { return _objectType; } }
private string _objectName = string.Empty; /// <summary> /// Gets the name of the object requested /// </summary> public string ObjectName { get { return _objectName; } }
private string _command = string.Empty; /// <summary> /// Gets the command to execute on the object /// </summary> public string Command { get { return _command; } }
private NameValueCollection _qs = new NameValueCollection(); /// <summary> /// Gets the querystring used in the call /// </summary> public NameValueCollection Qs { get { return _qs; } } #endregion
/// <summary> /// Process a uri and returns an object to be use by the ServiceHandlerFactory /// </summary> /// <param name="url">The uri object from the request</param> public UriProcessor(Uri url) { if (url.Segments.Length != 5) { throw new UriMalformedException(); } this._web = url.Segments[1].Replace("/", ""); this._objectType = url.Segments[2].Replace("/", ""); this._objectName = url.Segments[3].Replace("/", "");
string[] com = url.Segments[4].Split('.'); if (com.Length != 2) { throw new UriMalformedException(); } this._command = com[0]; this._returnFormat = com[1];
this._protocol = url.Scheme; this._domain = url.Host;
this._qs = HttpUtility.ParseQueryString(url.Query); } } } Custom ExceptionsWe want to throw custom exceptions, don't we? This is just in the works, only one class for now. using System;
namespace LaTrompa.Services { public class UriMalformedException : Exception { public UriMalformedException() : base("The uri has the wrong format") { } } } The HTTP HandlerWe will map the extentions that we won't to handle via the API to this Http Handler. using System; using System.Web;
namespace LaTrompa.Services { public class ServiceHandler : IHttpHandler { #region IHttpHandler Members
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context) { UriProcessor up = new UriProcessor(context.Request.Url); IServiceable service = ServiceHandlerFactory.Create(up); service.Process(context); }
#endregion } } You may notice that the HttpHandler doesn't handler the call but it use a Factory to create an object that implements IServiceable that will understand how to handle the call.
Yesterday Scott Gu post again about the MVC framework. Don't miss his post about Passing View data from controllers to view. There was some talk about the release date being this week, but that wont be the case. I think that is just fair to tell that we are all waiting for it. I just want to get my hands on the code, and have an old asp classic site that can be a great candidate to migrate using the framework.
In the altnet conference the guys from Microsoft presented an MVC framework that will be released on the spring. It promise to be something really good, it's seems to be so flexible that you can plug into it whatever framework you are used to do, for example, Nunit of MBunit for testing, Spring for DI or NVelocity as your template engine. The framework comes with all this already implemented but they don't force you to use their implementation if you don't want to. Visit Scot Hanselman's blog for two videos where ScottGu and Hanselman himself demo the framework and right some code. Hanselman does his presentation using IronPython and shows an alternative view engine. You will need at least two hours of quiet to really enjoy this presentations but they totally deserve it.
|