Microsoft

Tripping over logs: A story of Unity - Part 2

Submitted by Robert MacLean on Tue, 01/06/2009 - 18:52
Recap + Intro

In part 1 we looked at the problem with just adding logging code and how it quickly gets messy and we looked at how the more loosely coupled the code is, the easier it is to effect changes painlessly. Now we are going to take that “nicer” code (compared to the first version) and put Unity in the mix. Note you can get Unity with the Enterprise Library from p&p group.

As I said in part 1

what I am going to do is look at a practical approach to using Unity, I will not be going into DI or IoC those topics as people smarter than me have done a much better job. If you want the theory look somewhere else, if you want to get running with Unity this is for you.

This is a multi-part series as such here is the series guide in case you are looking for the rest of the series:

Applying Unity

The first step to using Unity is setting it up it, to do that you need to add three references to your solution (highlighted below):

image

Unity has two configuration options, one in code and one in an external configuration file (normally your app/web.config). They both have a use but for this series I will use the configuration file which means you also need to add a reference to:

image

I tend to find that the config file route is what I use in production while the code one is what I use in unit tests (normally to override config file settings).

Next add the references to your code:

using System.Configuration;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

Now in my main method of my application I am going to create an instance of an UnityContainer (line 21 below). This is effectively a magic bag, where we put our hand in and say what we want and pull it out - just like Mary Poppins had. Before we can do that we need to tell it to read the configuration information (lines 23 and 24 below) and then we retrieve the logger (line 26 below) from the magic bag. Note that we are NOT creating an instance of a logger on line 10 below as we did before, the act of pulling the logger out of the bag creates it.

   1: using System;
   2: using System.Configuration;
   3: using Microsoft.Practices.Unity;
   4: using Microsoft.Practices.Unity.Configuration;
   5:  
   6: namespace BigSystem
   7: {
   8:     class Program
   9:     {
  10:         static ILogger logger;
  11:  
  12:         static void DoSomething(string Username)
  13:         {
  14:             logger.LogThis("DoSomething Called with Username Parameter set to:" + Username);
  15:             Console.WriteLine("Hello {0}", Username);
  16:             logger.LogThis("DoSomething Completed");
  17:         }
  18:  
  19:         static void Main(string[] args)
  20:         {
  21:             IUnityContainer container = new UnityContainer();
  22:  
  23:             UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
  24:             section.Containers.Default.Configure(container);
  25:  
  26:             logger = container.Resolve<ILogger>();
  27:  
  28:             logger.LogThis("Application started");
  29:             DoSomething("Robert");
  30:             Console.ReadKey();
  31:             logger.LogThis("Application Completed");
  32:         }
  33:     }
  34:  
  35:     public interface ILogger
  36:     {
  37:         void LogThis(string Message);
  38:     }
  39:  
  40:     public class DebugLogger : ILogger
  41:     {
  42:         public void LogThis(string Message)
  43:         {
  44:             System.Diagnostics.Debug.WriteLine(String.Format("{0}: {1}", DateTime.Now, Message));
  45:         }
  46:     }
  47:  
  48:     public class ConsoleLogger : ILogger
  49:     {
  50:         public void LogThis(string Message)
  51:         {
  52:             Console.WriteLine("{0}: {1}", DateTime.Now, Message);
  53:         }
  54:     }
  55: }

Lastly we need to dive into the app.config (add one now if you are following at home) and fight the tangled web of Unity configuration.

Unity Config

We start off by adding a configSection to tell the framework how to handle the new section for Unity (this is lines 3 to 5). Then on line 7 we open our unity tag and the first thing in there is the typeAliases. I recommend using type aliases as they allow you to centrally link a type (like BigSystem.ILogger) to a friendly name. In our example below it’s overkill we could’ve just used the types directly on line 16 (I’ll cover that in a second) but as your solution grows doing find and replace for types is a pain and having this alias system will make life easier. So lines 9 and 10 alias my class and interface to a friendly name.

Now line 13 is where the meat comes in, we open the containers tag which allows up to setup our container which is just a named group of settings. We have one container so we do not need to name it, and in there is the types tag (line 15) which allows us to map what interface to what class, so we we call container.Resolve<ILogger> (line 26 in the code above) it knows what class to return.

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <configSections>
   4:         <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
   5:     </configSections>
   6:  
   7:     <unity>
   8:         <typeAliases>
   9:             <typeAlias alias="Logger" type="BigSystem.DebugLogger, BigSystem"/>
  10:             <typeAlias alias="ILogger" type="BigSystem.ILogger, BigSystem"/>
  11:         </typeAliases>
  12:  
  13:         <containers>
  14:             <container>
  15:                 <types>
  16:                     <type type="ILogger" mapTo="Logger" />
  17:                 </types>
  18:             </container>
  19:         </containers>
  20:     </unity>
  21: </configuration>

So if you run the code it will actually do the logging to the Output window in Visual Studio!

Then if we change line 9 above as such it will output to the console!

<typeAlias alias="Logger" type="BigSystem.ConsoleLogger, BigSystem"/>

This is not super cool because we just made it possible to externally say what class it should use without a recompile of code. You still need to have all the classes in your code already (think ahead) and we have made the logging any better than before. We will really get this improved in part 4 but for now we are moving in the right direction, even if it doesn’t seem like it.

Tripping over logs: A story of Unity - Part 1

Submitted by Robert MacLean on Tue, 01/06/2009 - 18:45

Welcome to the first part in my series on using Unity, which is a Dependency Injection or Inversion of Control tool/framework/thing from the p&p group. It’s a big and (over) complicated topic so if what I have just said means nothing, fear not for it will all make sense soon. I have broken this into a series to make it easier to digest. What I am going to do is look at a practical approach to using Unity, I will not be going into DI or IoC those topics as people smarter than me have done a much better job (part 6 has links). If you want the theory look somewhere else, if you want to get running with Unity this is for you.

This is a multi-part series as such here is the series guide in case you are looking for the rest of the series:

The Problem

A few years back I was developing an enterprise solution for a bank which integrated MSCRM into a number of systems, and so I needed to make sure I did logging (that’s what enterprise apps have, right?). Initially I had a simple “write to text file” logging system, which worked fine on my machine (if you can see what the problem is in that sentence you been developing too long). That is until we started testing and we ramped up the usage and I hit concurrency and locking issues. That prompted me to rip out all the logging and use the logging within System.Diagnostics.Trace as it seemed like it would work better, and it did for a long time. At some point I was pulled back to project (I left it for a long time) and needed to change the logging to use the p&p Enterprise Library logging. It was only at this point did I stop calling the System.Diagnostics.Trace code directly in each place for logging and start calling a custom method. This is what it sort of looked liked, excepted I had lots more parameters on the logging (level of message, source component etc…) and we logged every time something changed not just entry and exit:

public void DoSomething()
{
    LogThis("Do Something Start");
     ...
    LogThis("Do Something End");
}

When I changed it out I did some number crunching and realised that 40% of all the lines of code was these calls to logging! I remember thinking that was well done and how proud I was of my logging skills. Now days I look back at that as ridiculous. Not the fact I did logging, just how much code was spent on it and how tightly bound it was. So how could I do it better now days, well through a principal called Dependency Injection and an implementation of it called Unity (from the p&p team in their Enterprise Library).

Note: I am using the example of logging as the problem to solve, but really DI can be used for anything.

I must admit that Unity though is anything but simple, it is one of the hardest things I have had to learn in a while. What made it tough was understanding the documentation which enables you to learn Unity, but you need to understand Unity first to understand the documentation, talk about catch 22. It’s odd because the other blocks in EntLib are easy to get up and running but with Unity the samples are confusing and the help more so. In the end, some search kung fu + luck + patience seems to be what is needed to get through it. That said I feel a simple series of blog posts may help others out, which is what this is ;)

Starting Block

A special note is that this series is HEAVY with code and makes the articles look long, but actually I am repeating the code each time so you can compare the changes easily.

So lets start with a simple application as our base which will make it clear what we have and what we will change to get Unity working. As those who attend any of my sessions know I love console apps so I’ve whipped up a simple on that writes to the screen. The code looks like this:

using System;
 
namespace BigSystem
{
    class Program
    {
        static void DoSomething(string Username)
        {
            Console.WriteLine("Hello {0}", Username);
        }
 
        static void Main(string[] args)
        {
            DoSomething("Robert");
            Console.ReadKey();
        }
    }
}

And the solution like this (note the references - super clean):

image

Now using my “Enterprise Skills” from earlier, we add some logging like so:

static void LogThis(string Message)
{
    System.Diagnostics.Debug.WriteLine(String.Format("{0}: {1}", DateTime.Now, Message));
}
 
static void DoSomething(string Username)
{
    LogThis("DoSomething Called with Username Parameter set to:" + Username);
    Console.WriteLine("Hello {0}", Username);
    LogThis("DoSomething Completed");
}
 
static void Main(string[] args)
{
    LogThis("Application started");
    DoSomething("Robert");
    Console.ReadKey();
    LogThis("Application Completed");
}

Right, so that code is not bad. It works which makes the (imaginary) customer is happy. This code is not good either, because if we want to change anything it’s a big issue, likely “solved” by a find and replace. A better route would be to take the logging out and define it in a separate class that inherits from an interface. This means when we create the class we can change that one place and all the code is effected.  So that would look like this:

class Program
{
    static ILogger logger = new DebugLogger();
 
    static void DoSomething(string Username)
    {
        logger.LogThis("DoSomething Called with Username Parameter set to:" + Username);
        Console.WriteLine("Hello {0}", Username);
        logger.LogThis("DoSomething Completed");
    }
 
    static void Main(string[] args)
    {
        logger.LogThis("Application started");
        DoSomething("Robert");
        Console.ReadKey();
        logger.LogThis("Application Completed");
    }
}
 
public interface ILogger
{
    void LogThis(string Message);
}
 
public class DebugLogger : ILogger
{
    public void LogThis(string Message)
    {
        System.Diagnostics.Debug.WriteLine(String.Format("{0}: {1}", DateTime.Now, Message));
    }
}

Note the constructor for logger and the interface and class below. The reason this is powerful is if I wanted to change this to output to the console I could spin up a new class, and just change the constructor for logger, as in below:

class Program
{
    static ILogger logger = new ConsoleLogger();
 
    static void DoSomething(string Username)
    {
        logger.LogThis("DoSomething Called with Username Parameter set to:" + Username);
        Console.WriteLine("Hello {0}", Username);
        logger.LogThis("DoSomething Completed");
    }
 
    static void Main(string[] args)
    {
        logger.LogThis("Application started");
        DoSomething("Robert");
        Console.ReadKey();
        logger.LogThis("Application Completed");
    }
}
 
public interface ILogger
{
    void LogThis(string Message);
}
 
public class DebugLogger : ILogger
{
    public void LogThis(string Message)
    {
        System.Diagnostics.Debug.WriteLine(String.Format("{0}: {1}", DateTime.Now, Message));
    }
}
 
public class ConsoleLogger : ILogger
{
    public void LogThis(string Message)
    {
        Console.WriteLine("{0}: {1}", DateTime.Now, Message);
    }
}

This is great, except to change the type of logger I need to change the code. Wouldn’t it be better to

  1. Be able to specify in a configuration file what should be used?
  2. Instead of instantiating a logger (like with the constructor), I could have a bag where code could reach into and ask for a logger?

This is what Unity provides at a basic level and we will implement in the next post, but trust me it goes much further and becomes much more powerful.

Search better

Submitted by Robert MacLean on Tue, 01/06/2009 - 08:51

Something I have always thought of as a secret weapon in my skills is that search the Google has generally yielded good results or I find I am alone in my problem. I have found that others do not do this as well, often times they search - get nothing, come to me for help, I search and get what they need. Regardless there is a interesting game from MS research which shows you a page and you search for it (backwards to the norm) and score points for how high it appeared in the rank and if you didn’t use common phrases.

My gripe with it is that it has a timer (how many can you do in set time) and since it needs to load the pages, us poor South Africans with no bandwidth it makes the game go slower. I figure I could get 4 or 5 more pages in with decent bandwidth. Oh well, check out PageHunt

Thanks to Alfred for the heads up.

Scott Hanselman - Last night at Microsoft

Submitted by Robert MacLean on Tue, 12/09/2008 - 10:31

Being on the southern tip of the world and add the slowest bandwidth anywhere (confirmed by Scott himself) we seldom get the greats like Scott Hanselman out to talk to us, let alone for free, and when he is on holiday… but that is what the S.A. Developer community got last night and what a night it was. He spoke last night on MVC and I made some notes I thought I would share.

The first concept is that

  • ASP.NET > Web Forms
  • ASP.NET > MVC

It’s an interesting way of thinking that ASP.NET is not Web Forms, since it is normally that we use those two interchangeable. ASP.NET is a framework for building web applications, if we use web forms on that framework is a choice not a requirement. Web forms in itself is a lie, it tries to make us believe that the web is stateful… so that we get the RAD/VB6 experience for development. The problem is that like the Matrix, the lie constrains us. MVC is the anti-RAD in a way, it opens up a lot more to the developer than Web Forms traditionally does. Knowing there is a lie, and knowing the truth can hurt you (the same way Neo knew there was no gravity, yet fell) and so MVC can hurt you. MVC is NOT a replacement for Web Forms, it is another way to solve a set of problems and some problems are better solved in web forms, and others in MVC (or ASP.NET Dynamic Data).

MVC is made up of models, viewers and controls and all of these are changeable. So the viewers uses web forms to render the HTML, but there are other options. One of those is NHaml which is a very different way to create HTML (can read about it here) and I thought that looked very interesting. Viewers should contain no logic, they should focus on rendering HTML only. What is very nice is that for the rendering side JQuery is bundled directly into MVC! It is also important to note that ascx files (ASP.NET controls) are not a

Separate from the viewers is the controls which uses the ASP.NET Routing feature of 3.5 SP 1 heavily. It is very elegant in it’s implementation and shows a forward thinking of convention over configuration. In other words it if you type in a URL like http://test/account/view, it will first check in the viewers\account folder for a view.aspx or ascx file and then in the viewers\shared folder for a view.aspx or ascx file. No config to say that this URL maps to this file. Controllers should contain the bulk of the logic but should not have any web concepts (i.e. don’t use the Request object). Obviously you could, but this breaks the important separation in the MVC design. What is nice, is that because the design of MVC is to help enforce separation, unit testing is amazingly simple and if you have the full versions of Visual Studio then it even builds unit tests for you! So while it may be very easy to put some code in a controller to check if a user is authenticated, you need to decide what level of tolerance for code smell you can handle.

Separate still from both of those is the models. Which is your data model for example LINQ to SQL. The purest form of MVC is you have your data model and then a model to talk to controllers so there is a separation in the models and everything is clean. How much benefit that has in real world is unfortunately not that much and because you have the power (you took the red pill) you can share the model from the models to the controllers.

After that Scott showed his latest project, called NerdDinner. Which is based on MVC and will be an open source solution through CodePlex one day. He showed a lot of the code and highlighted the good bits and the bad bits. This really highlighted what he was talking about and some of the problems you need to solve when working with MVC. After that was Q&A with Pizza.

Defiantly one of the best talks I have attended in a long time. He is on his way to Cape Town (taking a day out of his holiday to fly specially to CT) so if you are in CT, you must go and see him! Details can be found on S.A. Developer!

Windows Azure

Submitted by Robert MacLean on Thu, 11/06/2008 - 16:36

Reading Paul Thurrott’s review on Windows Azure he mentioned that it is part of the Azure Services Platform or ASP! ASP is already used (twice) in the Microsoft domain for ASP (classic) and ASP.NET, which the non developer community do not understand are different, but it is also a TLA (three letter acronym) for application service provider… which is what Azure aims to be, and if someone at Microsoft actually thought the latter combination th

Dev4Devs!

Submitted by Robert MacLean on Thu, 09/11/2008 - 17:32

Earlier this year I attended a great event called Dev4Devs which is run by Microsoft on a Saturday morning at their offices and invites any developer to get up and present for 20mins! This is a great introduction into a lot of things as well as a great place to start if you want to become a presenter. Well it’s happening again in October! I will definitely be there so head over to Eben’s blog for more details.

Silverlight: Lessons Learnt

Submitted by Robert MacLean on Tue, 08/26/2008 - 22:11
Tech-Ed was a lot fun and the feedback for the session I did was more positive than negative. Being a speaker doesn't get you into too many special things (there is a speakers lounge) but one of the fun things it did get me this year was the chance to do a video session with my good friend Simon from BlackLight, who was also my co-speaker for my WPF talk. The video is about 15min long and I play the role of interviewer (Larry King watch out!) and I interview Simon on what he does everyday Silverlight and the lessons he has learnt in the last year and a bit.
To check the video go to http://technet.microsoft.com/en-us/events/teched/cc561184.aspx

Visual Studio 2008 Install

Submitted by Robert MacLean on Tue, 12/04/2007 - 13:52
So I had Visual Studio 2008 beta 2 installed and got my copy of the RTM media from Ryan today, so obviously I had to do the upgrade today. However I did have Ryan warning me of his experience with it (what made it worse was he didn't even have the beta installed). So I uninstalled the beta. Popped the disk in and it told me to uninstall the beta .Net 3.5 framework. Did that, ran the setup again and it worked, perfectly.

Dunno what else to say really. Normally these things are ammo for the annoyance tag but not today! However if you are unlucky like Ryan, read his post as he is getting some lovely info from MS on the comments.

Windows Vista Power Button

Submitted by Robert MacLean on Mon, 11/19/2007 - 09:23
In Vista there is the shiny new start menu with the shiny new turn off options, and until recently I have been using the fly out menu on lock to hit sleep or hibernate or shutdown etc... Thankfully I have gotten over that through two dumb luck experiences.

Firstly my home box I have been hitting the power button since it is quick to resume and I don't really worry about things. I always just thought it was putting it into sleep, well this weekend I stumbled across a new feature in Vista (well new to me) called help. It's amazing, it's like Google for windows off line Laughing

Seriously, in the help feature I found an article on what the power button does. Basically if you have an old machine the power button puts it into sleep. However if you have a more modern it puts it into hybrid sleep. This new mode, works like both hibernate and sleep in shutdown (i.e. it does both). Then when it needs to start up again it checks to see if the memory still contains the information (i.e. sleep mode) and if it does restores damn fast from that. If it doesn't contain (say due to power loss) then it restores from the hibernate information.

The power button is the ONLY way in the Vista interface to do this!

To check if you can use this or to turn it on/off go to power options (either off the battery icon in the task try or in the control panel), click Change Plan Settings on your selected power plan, next click Change Advanced Power Settings and under sleep you will see the options (see the attachment of this post for a screen shot).

SQL Server Express with Advanced Services

Submitted by Robert MacLean on Fri, 11/02/2007 - 09:45
This really is the worlds most needed, most hidden and most marketing bs item ever. For those who don't know SQL Server Express is the light version of SQL Server, basically runs a database server but nothing else, not even a management tool. However it is free to redist with apps and it ships with Visual Studio etc... so it's out there a lot.
But you can just feel there are things needed to get it from almost useless to void filling tool (management tools being number 1). Anyway someone at MS realized this at some point in the last year and decided to bring out the Advanced Services edition (how is that for marketing spin, it should be the complete edition but no we need it to be advance, even though it install stripped down features of everything still).
Anyway above the standard express you get:
  1. Stripped down management tool
  2. Reporting services server (the /ReportServer, you don't get /Reports)
  3. and full text search.
These features are so advanced it's insane, oh wait they are all in the standard SQL server from day one.
Anyway if you need this you can get the 250 odd MB download, which you can just run on your vanilla SQL express to upgrade it, from
http://www.microsoft.com/downloads/details.aspx?familyid=5B5528B9-13E1-4DB9-A3FC-82116D598C3D&displaylang=en
More details on this is available at
http://msdn2.microsoft.com/en-us/library/ms365248.aspx