06 Jan 2009

Tripping over logs: A story of Unity - Part 2

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.

06 Jan 2009

Tripping over logs: A story of Unity - Part 1

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.

30 Dec 2008

Installing MSMQ in Domain Mode on Windows Server 2008

Yesterday I needed to install MSMQ on my laptop which runs Windows Server 2008, which wasn’t as logical as it first appeared. I simply fired up the Server Manager tool, went to features, selected Message Queuing and clicked next. However my code kept giving me an error: “This operation is not supported for Message Queuing installed in workgroup mode.”

So I went to find out what this mean, and it turns out MSMQ has two modes workgroup and domain. Domain is the “yes you can” mode where everything works while workgroup has restrictions:

The following restrictions exist when using Message Queuing in workgroup mode:

  • Computers in workgroup mode require direct connectivity with a destination computer, and only support direct message transmission. Messages sent by such computers cannot be routed.
  • There is no access to Active Directory Domain Services. As such, you can create and manage private queues only on a local computer. You can view the list of private queues on another computer, and the messages in them, using the Computer Management snap-in. For information about managing queues on remote computers, see Verwalten von Warteschlangen auf anderen Computern. You cannot view or manage public queues or any other information in Active Directory Domain Services. You can, however, send messages to or retrieve messages from private queues if there is direct connectivity.
  • Internal certificates cannot be used for sending authenticated messages; an external certificate must be used. For more information about user certificates, see User Certificates.
  • Messages cannot be encrypted. For more information about encryption, see Encryption for Message Queuing.
  • There is no support for dependent clients. For more information about restrictions on the deployment of dependent clients, see Dependent Clients.
  • Cross-platform messaging is not supported. For more information, see Cross-Platform Messaging.

That is taken from the helpful TechNet page Deploying in Workgroup Mode, which also states:

The default installation setting is that the directory service Integration feature is installed

Oddly enough though that is NOT what I got, in fact when I went to check Directory Service Integration had not been installed even though I am on a domain (and was connected to the network at the time)! To fix it, I had to go back to the Server Manager Tool, Features, Message Queuing and manually select it.

 

Clipboard01

30 Dec 2008

TFS Branching Guidance is Out

Very late notice from me (been sitting in my inbox for 2 weeks) but the TFS branching guidance is now out on CodePlex: http://dotnet.org.za/willy/archive/2008/12/20/vsts-branching-guidance-ii-a-great-guidance-release.aspx

Interesting it’s the 25th highest download on CodePlex at the moment too! Guess it shows that it isn’t just me and Ryan spending a lot of time trying to figure out the perfect strategy!

19 Dec 2008

.NET 3.5 SP 1 GDR is Out

The .NET 3.5 SP 1 GDR (General Distribution Release), basically the patch for the bugs in .NET 3.5 SP 1, is now out! Details of the patch are/will be available at KB959209

17 Dec 2008

The Cat(.NET) is out of the bag

Those who know me as a developer, and those who attended the boot camp I ran for the last two weeks, have an idea that I  like analysis tools (in the boot camp I present a session on my favorite 7 tools, 3 of them are analysis tools). That said I have been following a team at Microsoft for ages who have been building a tool called CAT.NET, which is another static analysis tool. This one focuses on analyzing code for security issues. I looks good, but it really doesn’t blow me away.

What’s the first thing you do when you get a new tool? Run it against your own code and then the Microsoft code ;) No where could I get this code to ever give me a security issue – which is either a good or bad thing. When it’s done it provides a report in HTML and XML which is boring as hell:

Clipboard02

The report on System.Web.Services.dll

To see a problem I looked at the rules, which are defined in XML, to actually force an issue.  I decided to take a stab at the process command execution rule, with the amazingly complex code like this:

image

This produced a nice report like this:

image

That said during one of my tests with it I did get a different result, a nice crash when checking System.Data.dll

image

StackOverflowException in the security application.

But none of the above is the reason why it does not blow me away, it doesn’t blow me away because it’s another tool that is actually not needed. Looking at the files and code (thanks to reflector) this could have easily been built into FXCop and made that a better solution overall. It is in beta still, so hopefully this is an indication of a tool that has been grown in the dark and now that the light of the public the team will start to understand real world scenarios.

image

If you needed an indication of the beta status of this tool, check out how many NotImplementedExceptions are in the code still :(

You can download the bits here: 32 Bit or 64 Bit

10 Dec 2008

BizTalk 2009 Beta Out

Look at what I just found by searching for BizTalk on the connect site.

image

09 Dec 2008

Scott Hanselman - Last night at Microsoft

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!

Pages