Patch Producing Pal

June 19, 2009 at 11:47 PMAndre Loker

My contribution to the OSS community for today:

fnh-patches

http://code.google.com/p/fluent-nhibernate/issues/list

Posted in: NHibernate

Tags: , , ,

Meine Top 3 Dev Tools

May 19, 2009 at 9:53 AMAndre Loker

Mal wieder ausnahmsweise ein deutscher Beitrag. MSDN Deutschland ruft die Bloggemeinde auf, Ihre Lieblings Entwicklertools zu verkünden und lockt mit Gewinnen zur Befriedigung des Spieltriebs. Da will ich natürlich nicht hinten anstehen. Hier also zunächst meine persönliche Top 3 der Entwicklertools:

  • Visual Studio 2008. Keine Überraschung, zugegeben. Aber machen wir uns nichts vor, VS ist nun mal die IDE für .NETler und Plattform für eine Menge nützlicher Add-Ins.
  • ReSharper. Wieder keine Überraschung. Aber das Tool ist mir dermaßen in Fleisch und Blut übergegangen, dass ein arbeiten ohne R# wie eine Qual vorkommt. Mit ReSharper „strömt“ mir der Code quasi aus den Fingerspitzen. Und nein, ich arbeite nicht für JetBrains.
  • NAnt. Mein persönliches Schweizer Taschenmesser und Mädchen für alles: vom automatisierten Build bis hin zum Server-Backup, im Grunde gibt es nichts, was sich damit – mehr oder weniger elegant – steuern ließe. Auch wenn einige Entwickler mittlerweile rake verwenden, bleibe ich vorerst bei NAnt, da es sich mMn leichter deployen lässt.

Aber nur drei Tools zu nennen wäre recht eingeschränkt. Hier eine Auswahl von Tools, die für mich wichtig bis unentbehrlich sind:

  • Subversion, das Version Control System meiner Wahl. Mittlerweile bevorzugen viele git. Ich mag dessen Konzept, aber die Unterstützung von git für .NET-Entwickler ist im Moment besser.
  • TortoiseSVN kennt wohl jeder, der Subversion unter Windows einsetzt.
  • VisualSVN + VisualSVN Server. Nunja, besagte Unterstützung für .NET-Entwickler :-)
  • Testdriven.NET: Noch ein VS Add-In, dass wohl fast jeder kennt. Schneller kann man seine – in meinem Fall MbUnit - Unit Tests wohl nicht ausführen.
  • .NET Reflector, machmal ist Quellcode halt die beste Dokumentation!
  • CruiseControl.NET, mein bevorzugter Continuous Integration server.
  • CCNetConfig, Konfigurationstool für CruiseControl.NET
  • MS Sql Server Manament Studio 2008 – Code completion in Queries find ich richtig gut!
  • Notepad++, schlanker Text editor mit einer Menge Funktionen
  • dotTrace. Keine Ahnung warum die Anwendung lahmt? Dieser Profiler könnte helfen.
  • Balsamiq Mockups – Richtig cooles Tool um UI Attrappen zu basteln. Vor allem für die Kundenkommunikation hilfreich.
  • NDepend. Ich nenn es gerne “Code Qualität in Zahlen”.
  • NCover. Code coverage ist ebenfalls eine wichtige Metrik.

Da es hier um tools geht, habe ich meine Lieblingsbibliotheken an dieser Stelle außer Acht gelassen.

Hier noch einmal der Link zum MSDN Blogeintrag.

Posted in: Tools

Tags: , ,

ReSharper 4.5 gone gold

April 8, 2009 at 10:21 PMAndre Loker

JetBrains has released version 4.5 of their multi purpose productivity plugin for Visual Studio, ReSharper. This updates contains some pretty cool features. For example, solution wide analysis now checks for members that can be made internal. Also, JetBrains promises to have improved performance and memory use. All in all certainly an update that is worth installing, especially because updating from licenses for version 4.0 and above is free. Maybe I’ll give a more in-depth review if I find the time.

If you want to know more about ReSharper, check out my little overview page. There you’ll also find information on how to get an additional 60 days of free evaluation. Have fun!

Posted in: Tools

Tags:

ASP.NET MVC with Windsor – programmatic controller registration

March 28, 2009 at 11:29 AMAndre Loker

Although I’m a loyal MonoRail user, I’m playing with ASP.NET MVC a bit sometimes if time permits. One of the first things I wanted to do is using an IoC container such as Windsor to resolve controllers. ASP.NET MVC was built with extensibility in mind, so that’s not much of a problem, and it has been written about, for example by Matt Hall.

The problem is that the articles I read use the Windsor XML configuration for this. Frankly, I don’t like to configure my IoC container using XML if I don’t have to. Its syntax is pretty verbose and honestly I don’t need the controllers to be configured externally. Therefore, I prefer to use programmatic registration. Windsor has such a sweet registration API, you got to love it.

Alright, so what do you have to do to make programmatically registered controllers available to ASP.NET MVC?

Step 1 – create the container instance

This is easy: in the Application_Start event create the WindsorContainer and store it in a static(!) field. It has to be static, because more than one instance of the HttpApplication can potentially be created.

 

   1: public class MvcApplication : System.Web.HttpApplication {
   2:   static IWindsorContainer container;
   3:  
   4:   protected void Application_Start() {
   5:     CreateWindsorContainer();
   6:     RegisterRoutes(RouteTable.Routes); // has been there before!
   7:   }
   8:  
   9:   static void CreateWindsorContainer() {
  10:     container = new WindsorContainer();
  11:   }
  12: }

Did I mention that the container field needs to be static?

Step 2 – register controllers

This is where the nice API of Windsor comes into play. Extend the application as follows:

   1: public class MvcApplication : System.Web.HttpApplication{
   2:   ...
   3:  
   4:   protected void Application_Start() {
   5:     CreateWindsorContainer();
   6:     RegisterRoutes(RouteTable.Routes);
   7:     RegisterControllers(); // added
   8:   }
   9:  
  10:   ...
  11:  
  12:   static void RegisterControllers() {
  13:     container.Register(
  14:       AllTypes
  15:         .FromAssembly(Assembly.GetExecutingAssembly())
  16:         .BasedOn<IController>()        
  17:     );
  18:   }
  19: }

This is simple, isn’t it? No per-controller-entry in some XML file, just a simple piece of code.

Step 3 – create your own controller factory

To create the controller instances, ASP.NET MVC uses an object that implement IControllerFactory. So all we need to do is roll our own controller factory that uses Windsor and tell ASP.NET MVC to use that.

OK, so here’s our controller factory:

   1: public class WindsorControllerFactory : IControllerFactory {
   2:  
   3:   readonly IWindsorContainer container;
   4:  
   5:   public WindsorControllerFactory(IWindsorContainer container) {
   6:     this.container = container;
   7:   }
   8:  
   9:   public IController CreateController(RequestContext requestContext, string controllerName) {
  10:     var componentName = GetComponentNameFromControllerName(controllerName);
  11:     return container.Resolve<IController>(componentName);
  12:   }
  13:  
  14:   public void ReleaseController(IController controller) {
  15:     container.Release(controller);
  16:   }
  17:  
  18:   /// <summary>
  19:   /// Maps from a simple controller name to the name of the component
  20:   /// that implements the controller.
  21:   /// </summary>
  22:   /// <param name="controllerName">Name of the controller.</param>
  23:   /// <returns>Name of the controller component.</returns>
  24:   static string GetComponentNameFromControllerName(string controllerName) {
  25:     var controllerNamespace = typeof(HomeController).Namespace;
  26:     return string.Format("{0}.{1}Controller", controllerNamespace, controllerName);
  27:   }
  28: }

Nothing fancy here: first, we’ll need the windsor container instance, so we pass it as a constructor dependency. CreateController and ReleaseController are the two methods of IControllerFactory – their purpose should be self-explanatory. GetComponentNameFromControllerName maybe needs some further explanation. ASP.NET MVC will ask for controllers by their simple name, that is “Home” or “About” etc. However, by the way we registered the controller components Windsor knows them by their full type name, e.g. “MyApplication.Controllers.HomeController” and “MyApplication.Controllers.AboutController”. GetComponentNameFromControllerName simply converts from the simple controller name to the full component name.

Step 4 – tell ASP.NET MVC to use our controller factory

The last step is to tell ASP.NET MVC to actually use our IControllerFactory implementation instead of the default one. Conceptually this is easy, we only need to call ControllerBuilder.Current.SetControllerFactory and pass it either the type of our IControllerFactory implementation or an instance. But let’s not be too quick here and try to keep our application as DI-ish as possible. Here’s how I’d set the controller factory:

   1: public class MvcApplication : System.Web.HttpApplication{
   2:   ...
   3:  
   4:   protected void Application_Start() {
   5:     CreateWindsorContainer();
   6:     RegisterRoutes(RouteTable.Routes);
   7:     RegisterControllers();
   8:     RegisterControllerFactory(); // new
   9:   }
  10:   
  11:   void RegisterControllerFactory() {
  12:     container.Register(
  13:       Component
  14:         .For<IControllerFactory>()
  15:         .ImplementedBy<WindsorControllerFactory>()
  16:         .LifeStyle.Singleton
  17:       );
  18:     var controllerFactory = container.Resolve<IControllerFactory>();
  19:     ControllerBuilder.Current.SetControllerFactory(controllerFactory);
  20:   }
  21:  
  22:   static void CreateWindsorContainer() {
  23:     container = new WindsorContainer();
  24:     // new: register the container with itself 
  25:     //      to be able to resolve the dependency in the ctor
  26:     //      of WindsorControllerFactory
  27:     container.Register(
  28:       Component
  29:         .For<IWindsorContainer>()
  30:         .Instance(container)
  31:       );
  32:   }  
  33:  
  34:   ...
  35: }

You see, instead of new-ing an instance of WIndsorControllerFactory we register it as a singleton component and resolve it. Also note that we needed to register the Windsor container with itself to have the constructor dependency resolved.

Finally, here’s the complete source code of the global application class so far:

   1: public class MvcApplication : System.Web.HttpApplication {
   2:   static IWindsorContainer container;
   3:  
   4:   public static void RegisterRoutes(RouteCollection routes) {
   5:     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   6:  
   7:     routes.MapRoute(
   8:       "Default", // Route name
   9:       "{controller}/{action}/{id}", // URL with parameters
  10:       new { controller = "Home", action = "Index", id = "" } // Parameter defaults
  11:       );
  12:   }
  13:  
  14:   protected void Application_Start() {
  15:     CreateWindsorContainer();
  16:     RegisterRoutes(RouteTable.Routes);
  17:     RegisterControllers();
  18:     RegisterControllerFactory();
  19:   }
  20:  
  21:   static void CreateWindsorContainer() {
  22:     container = new WindsorContainer();
  23:     container.Register(
  24:       Component
  25:         .For<IWindsorContainer>()
  26:         .Instance(container)
  27:       );
  28:   }
  29:  
  30:   static void RegisterControllers() {
  31:     container.Register(
  32:       AllTypes
  33:         .FromAssembly(Assembly.GetExecutingAssembly())
  34:         .BasedOn<IController>()
  35:       );
  36:   }
  37:  
  38:   static void RegisterControllerFactory() {
  39:     container.Register(
  40:       Component
  41:         .For<IControllerFactory>()
  42:         .ImplementedBy<WindsorControllerFactory>()
  43:         .LifeStyle.Singleton
  44:       );
  45:     var controllerFactory = container.Resolve<IControllerFactory>();
  46:     ControllerBuilder.Current.SetControllerFactory(controllerFactory);
  47:   }
  48: }

Controller names and component names revisited

As you saw in step 3, we need to map the controller names to component names. This doesn’t take much effort and is my preferred way of handling this. But of course, you can already register the controller components with the respective controller names in the first place if you like. Just change the controller registration to something like this:

   1: static void RegisterControllers() {
   2:   container.Register(
   3:     AllTypes
   4:       .FromAssembly(Assembly.GetExecutingAssembly())
   5:       .BasedOn<IController>()
   6:       // modify the name with which the component is registered:
   7:       .Configure(component => component.Named(ControllerNameFromType(component.Implementation)))
   8:     );
   9: }
  10:  
  11: static string ControllerNameFromType(Type implementation) {
  12:   const string ControllerSuffix = "Controller";
  13:   var name = implementation.Name;
  14:   Debug.Assert(name.EndsWith(ControllerSuffix));
  15:   return name.Substring(0, name.Length - ControllerSuffix.Length);
  16: }

If you do this, you can remove the GetComponentNameFromControllerName method and simplify the implementation of IControllerFactory.CreateController to this:

   1: public IController CreateController(RequestContext requestContext, 
   2:                                     string controllerName) {
   3:   return container.Resolve<IController>(controllerName);
   4: }

Which version you choose is more or less a matter of taste. If you keep the full type name as the component’s name you reduce the chance for name clashes. However, if you register the components using the controller name creating the controller is slightly simpler.

More simplifications

You can even simplify the controller factory a bit if you inherit from DefaultControllerFactory instead of implementing IControllerFactory. Because DefaultControllerFactory will resolve the correct component type for you, you can simply override GetControllerInstance instead of implementing CreateController:

   1: public class WindsorControllerFactory : DefaultControllerFactory {
   2:   readonly IWindsorContainer container;
   3:  
   4:   public WindsorControllerFactory(IWindsorContainer container) {
   5:     this.container = container;
   6:   }
   7:  
   8:   protected override IController GetControllerInstance(System.Type controllerType) {
   9:     return container.Resolve(controllerType) as IController;
  10:   }
  11:  
  12:   public override void ReleaseController(IController controller) {
  13:     container.Release(controller);
  14:   }
  15: }

If you need to change the way that the controller name is mapped to a component type, you can also override GetControllerType.

MVC Contrib

As far as I know Windsor integration is also part of the MVC Contrib project. I haven’t looked into it, so bear with me if this article doubles existing code!

Posted in: ASP.NET | Castle

Tags: , , ,

Debugging speed of Gallio fixtures – reloaded

March 25, 2009 at 10:19 PMAndre Loker

Last week I mentioned the slow debugging of Gallio unit tests. After having published that blog post I had a conversation with Jeff Brown about this issue. After showing him in a video how huge the difference in speed between debugging an MbUnit 2.4 and an MbUnit 3 test was he pointed out that this might have to do with the fact that MbUnit 2.4 uses the multi threaded apartment state (MTA) per default, while MbUnit 3 uses single threaded apartment state (STA).

I tested this difference by debugging the test fixture shown below:

   1: [TestFixture]
   2: public class CalculatorTests {
   3:  
   4:   [Test, ApartmentState(ApartmentState.STA)]
   5:   public void Adding2And3ShouldReturn5_STA() {
   6:     TheTest();
   7:   }
   8:  
   9:   [Test, ApartmentState(ApartmentState.MTA)]
  10:   public void Adding2And3ShouldReturn5_MTA() {
  11:     TheTest();
  12:   }
  13:  
  14:   void TheTest() {
  15:     var x = 2;
  16:     var y = 3;
  17:     var expected = x + y;
  18:     var sut = new Calculator();
  19:     var actual = sut.Add(x, y);
  20:     Assert.AreEqual(expected, actual);
  21:     MessageBox.Show("END OF TEST!");
  22:   }
  23: }

And indeed: the STA unit test ran sluggish as reported while the MTA based unit test could be debugged at virtually the same speed as I am used to from MbUnit 2.4 tests.

I reported that back to Jeff and he proposed to change the default thread apartment state to MTA with the option to override this default using an assembly scoped attribute (for unit tests that require STA).

Thumbs up to Jeff!

Update:

Jeff reported that after some further research the solution to the problem might not be as simple as this and he needs to think it over. Anyway, I’m glad to see that this issue is being worked on.

Posted in: Tools

Tags: ,