Friday, August 03, 2007

Decorator - The Cool Pattern with the Stupid Name

So I have a logging class that is implementation agnostic.  Under the hood it uses an Adapter for Enterprise Library Logging, however we could easily switch it out for log4net if needed without changing the code.

So you can imagine that I have an interface that looks like this:

public interface ILogger

{

    void Write(string text);

    void Warn(string text);

    void Error(string text, Exception msg);

}

… and there is currently an implementation of this class called EntLibLogger:

public class EntLibLogger : ILogger

{       

    public void Write(string text)

    {

        //ent. lib write log entry

    }

 

    public void Warn(string text)

    {

        //ent. lib warn

    }

 

    public void Error(string text, Exception msg)

    {

        //ent. lib error

    }       

}

The specific logger that is used is abstracted behind a factory of course.  However, some of the applications that use this component will not have the logging configuration.  It is perfectly feasible to ignore logging in this scenario (ie: swallow exceptions) however this is something that any logging component would do.  I don’t want to add it to each and every implementation of ILogger.

So here’s where the decorator comes in.  This pattern could really use a better name, but I can’t think of one, so I’ll leave that up to you.

A Decorator implements the same interface, however it wraps each method with its own behavior before deferring the call to an inner implementation.  Wow, that doesn’t really make much sense, so how about an example…

public class SilentlyFailLoggingDecorator : ILogger

{

    private readonly ILogger _innerLogger;

 

    public SilentlyFailLoggingDecorator(ILogger innerLogger)

    {

        _innerLogger = innerLogger;

    }

 

    public void Write(string text)

    {

        try

        {

            _innerLogger.Write(text);

        }

        catch

        {

            //swallow exception

        }

    }

 

    public void Warn(string text)

    {

        try

        {           

            _innerLogger.Warn(text);               

        }

        catch

        {

            //swallow exception           

        }

    }

 

    public void Error(string text, Exception exc)

    {

        try

        {

            _innerLogger.Error(text, exc);

        }

        catch

        {

            //swallow

        }

    }

 

}

All of the actual implementation comes from whatever ILogger is sent via the constructor.  All this class does is “decorate” the method calls with additional behavior.  (This time, we’re choosing to silently ignore errors rather than throw exceptions that cause the program to stop)

To wire this up, wherever the factory method resides that creates the actual logger, you’d write…

public static ILogger GetLogger()

{

    //via IoC or just hard-coding

    return new SilentlyFailLoggingDecorator(

         new EntLibLogger()

    );

}

So there you have it!  The decorator pattern can do all kinds of Aspect-Oriented things such as Log a message each time a method is called, or possibly massage parameters before sending them to an inner class.

Sunday, July 29, 2007

My Presentation at OKCodeCamp - DDD with NHibernate

I presented a talk on Domain Driven Design with NHibernate at the OKC code camp yesterday.

It started out a bit rough because I had some missing references and some confusing exceptions, however once I got the ball rolling I think it went pretty well.

I ran way short on time, however, and I promised the crowd that I would post the completed files on my blog tonight .

So, here is the powerpoint, demo applications, and all of the referenced dlls from my presentation.  Let me hear your feedback in the comments!

File Attachment: ddd with nhibernate.zip (7694 KB)

(the file is large because I have the complete references to specific versions of NHibernate and NUnit, so you shouldn’t have to worry about references at all.)

To get the sample running, change the app.config to point to an actual database.  The database should be empty.

Friday, March 09, 2007

Writing a Simple Image Editor in CAB - Part 2

So after part 1, we have a shell ready to go.  We haven’t done anything CABish yet, but we will in this post.

The first thing we need to do is create our layout that modules will be loaded into.  If you remember, CAB Shells basically contain 2 possible things:  Workspaces and UI Extension sites.  It just so happens that we’ll need both!

First, we’ll need a menu for loading the image and applying filters.  That will be our UI Extension Site.

Second we need a workspace in which to load the image display module.

Our first UI Extension Site

Here I added a MenuStrip and created our default File menu.  Give it a name like mainMenuToolStrip so that you can refer to it later.

Next we want to add a workspace so that we can load the image.  To gain access to these CAB UI controls, you need to add them to the toolbox on the left.  Right click on the Toolbox Pane, select Add Tab and name it CAB Controls.  Then right click on the name and select Choose Items.  You’ll have to Browse for the Microsoft.Practices.CompositeUI.WinForms.dll.  Select all of the controls and click OK.

Now you should see a toolbox group like this:

CropperCapture[43]

We will use the DeckWorkspace control.  Drag that onto the form and name it mainWorkspace.  Make sure that you dock it to fill the form.

It should look like this:

CropperCapture[44]

We have our basic form, now it’s time to load the first module into it!

Create a new class library project called ImageDisplayModule.  Rename Class1.cs to ImageDisplayModuleInit.cs.  You’ll need a reference to the dlls mentioned above as well.

If you recall, a module contains work items.  Our first work item is DisplayImageWorkItem.  It’s responsibility is to load an image and display it on the form.

Let’s start out by creating the View.  The view is a user control with a [SmartPart] attribute applied.  The view is going to consist of an ImagePlaceHolder.   Also keep in mind that we are doing this with Model-View-Presenter, so we’ll start by identifying the interface for our view.

Create an interface called IDisplayImageView.  The only real member that this interface ensures is that you can set and retrieve an image.

public interface IDisplayImageView

{

    public Bitmap Image

    {

        get;

        set;

    }

 

}

Next, create a new UserControl called DisplayImageView.  This user control needs to implement the IDisplayImageView interface.  Also notice that I have placed the [SmartPart] attribute on the class as well.

using System;

using System.Drawing;

using System.Windows.Forms;

using Microsoft.Practices.CompositeUI.SmartParts;

 

namespace ImageDisplayModule.cs.WorkItems

{

    [SmartPart]

    public partial class DisplayImageView : UserControl, IDisplayImageView

    {

        private Bitmap _image;

 

        public DisplayImageView()

        {

            InitializeComponent();

        }

 

        #region IDisplayImageView Members

 

        public Bitmap Image

        {

            get { return _image; }

            set { _image = value; }

        }

 

        #endregion

    }

}

 Next, we’ll switch over to design view and drag a PictureBox on the control.  I’ve also added a dummy label so that we can identify this control on the form in a minute.

Here’s what it looks like:

CropperCapture[45]

I’ve also created a presenter that will control all of the UI logic for this view:

public class DisplayImagePresenter

{

    private IDisplayImageView _view;

 

    public DisplayImagePresenter(IDisplayImageView view)

    {

        _view = view;

    }

 

    [EventSubscription("topic://ImageEditor/ImageDisplayModule/ImageLoaded", Thread=ThreadOption.UserInterface)]

    public void OnImageLoaded(object sender, DataEventArgs<Bitmap> e)

    {

        _view.Image = e.Data;

    }

}

Here you can see that the view is accepted in the construtor, and we are responding to an event.  The topic:// is just a hierarchical way of naming events that we might care about.  Basically the presenter is going to listen for an event when a picture is loaded, and set the image to the view once it fires.

In order to load this module into our shell, we need a few more pieces.  The first is a ProfileCatalog.xml file.  This tells the shell what modules to load.

Place an xml file in the shell project and make sure that the properties are set to Copy Always so that it will end up in your output directory.  The file should look like this:

<?xml version="1.0" encoding="utf-8" ?>

<SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile">

  <Modules>

    <ModuleInfo AssemblyFile="ImageDisplayModule.dll" />

  </Modules>

</SolutionProfile>

The important concept to grasp here is that there is no project level reference to the module project.  The dll is placed directly in the shell’s bin folder, and CAB is going to read this file to know to load it.

When CAB goes to load a module, it will scan the assembly for a class that inherits from ModuleInit.  So, I created an ImageDisplayModuleInit class :

public class ImageDisplayModuleInit : ModuleInit

{

    private WorkItem _rootWorkItem;

    [ServiceDependency]

    public WorkItem RootWorkItem

    {

        get { return _rootWorkItem; }

        set { _rootWorkItem = value; }

    }

 

    public override void Load()

    {

        base.Load();

 

        //create workitem

        DisplayImageWorkItem wi = RootWorkItem.WorkItems.AddNew<DisplayImageWorkItem>();

 

        //run the workitem

        wi.Run();

    }

Here we take a reference to the Root WorkItem, which is provided to us through the [ServiceDependency] attribute from ObjectBuilder.  The Load() method is called which instantiates our work item and runs it.

The work item then needs to load up any smartparts and place them in the required workspaces.

public class DisplayImageWorkItem : WorkItem

{

    private IDisplayImageView _view;

    private DisplayImagePresenter _presenter;

 

    protected override void OnRunStarted()

    {

        base.OnRunStarted();

 

        ShowView();

    }

 

    private void ShowView()

    {

        //create the view

        _view = this.SmartParts.AddNew<DisplayImageView>();

        _presenter = new DisplayImagePresenter(_view);

 

        this.Workspaces["mainWorkspace"].Show(_view);

    }

}

This part is pretty self explanatory.  We take the workspace name from the shell and tell it to show our smart part.

Everything is wired up now, so if you run the application you should see that the module has been loaded into the shell.

the app running with a module loaded

If you have troubles getting everything to work, make sure that your Module project is setup to output the dll inside the Shell’s bin folder, and also verify that the profile catalog xml file is placed there as well.

Next time we’ll figure out how to load the image using a different workitem.