Doing .NET the "hard" way

One of my favorite tools for .NET development is the dependency injection framework StructureMap from Jeremy D. Miller. It's free and it's Open Source, but it's only available in the Windows world. Compared to Castle Windsor, StructureMap is much more lightweight and compact, but with the recent enhancements in the upcoming release just as powerful.

So I thought, it couldn't be so hard, to make StructureMap work with Mono and package it for Debian, but actually, it's not THAT easy.

The heavy usage of .NET 3.5 features, like lambdas, requires a recent development version of Mono. Took me 2-3 hours to have Mono and Monodevelop compiled from SVN and installed in parallel to my old Mono packages to /opt/mono. But that's working fine now.

The StructureMap VS2008 solution loads fine in Monodevelop, which makes life a lot easier. The only 3'rd party-dependency that StructureMap has, is Rhino.Mocks (another of my favorite development tools). The Rhino.Mocks assembly seems to work with Mono, but compiling it from source is probably much harder, because of it's dependency to DynamicProxy, so I decided to leave that by side for now, skip StructureMap.Automocking and concentrate on the core parts of StructureMap.

After working about a week on this, I already found three bugs in the Mono C# compiler, but the good news is, that StructureMap now compiles fine with some small patches (that Jeremy hopefully will include in the upcoming release).

Luckily, StructureMap is very well covered with unit tests, which makes testing it on Mono much easier. The state of affairs is, that most of the tests go green. I have about 70 failures within more then 600 tests and I'm pretty confident, that I can solve the remaining issues as well.

Published on 21/08/2008 at 01:19 by , tags , , , , ,

StructureMap Singelton

It’s now the second time that I did this mistake, so I mainly write this down here, to remember myself, not to make the same mistake again.

StructureMap allows to define a plugin family to be singleton. e.g.:

[PluginFamily("ApplicationShell", IsSingleton = true)]
public interface IApplicationShell
{
    ...
}

[Pluggable("ApplicationShell")]
public class MainForm: Form, IApplicationShell
{
    ...
}

So when requesting an instance of IApplicationShell from StructureMap, it will return an instance of MainForm. And it will return the same instance every time, so that only one single instance of MainForm exists - a Singleton.

But now add another interface:

[PluginFamily("ApplicationShell", IsSingleton = true)
public interface IDockingManager
{
   ...
}

[Pluggable("ApplicationShell")]
public class MainForm: Form, IApplicationShell, IDockingManager
{
    ...
}

Without thinking to much about this, you might assume, that creating an IApplicationShell and an IDockingManager now might return the same singleton MainForm instance. But: Nope! This will create two different instances of MainForm. Good bye Singleton!

StructureMap keeps track of singletons per PluginFamily / interface, not for the implementation of interfaces. In such case it probably would be nice to be able to configure MainForm as a Singleton and not the interface(s) it implements. I think this isn’t possible by configuration, but it can easily be done in code like this:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    // create  single instance of MainForm
    MainForm form = ObjectFactory.GetInstance<MainForm>();

    // always resolve IApplicationShell to this instance
    ObjectFactory.Inject<IApplicationShell>(form);

    // always resolve IDockingManager to this instance
    ObjectFactory.Inject<IDockingManager>(form);

    Application.Run(form);
}

Published on 14/02/2008 at 16:09 by , tags , , , , ,

New StructureMap on the horizon

Since a week or so, I’m using the latest StructureMap SVN snapshot in one of my projects. I’m a big fan of StructureMap and prefer it over Windsor, because most of my use cases don’t require very complex DI stuff. Most of the time I’m injecting IView’s or IService’s into Controller’s and StructureMap makes this as easy as:

[PluginFamily("View")]
public interface IView
{
}

[Pluggable("View")]
public class View: IView
{
}

public class Controller
{
    public Controller(IView view)
    {
    }
}

But back to the new StructureMap features. In the last version it was necessary to configure the Controller class from the above example as well, to be able to instantiate it from the StructureMap DI container:

[PluginFamily("Controller"), Pluggable("Controller") ]
public class Controller
{
 ....

In the upcoming StructureMap release every concrete class can be configured without explicitly configuring it (provided that all constructor dependencies can be resolved). This wasn’t too hard to do in the previous release with ObjectFactory.FillDependencies<ConcreteClass>(), but to be honest, I never thought of using this and am happy, that I can now get rid off some of the “attribute noise”.

Much more interesting is the new ability to pass parameters to the constructor, when instantiating a class through the DI container:

public class Controller
{
    public Controller (IService service, Parameter parameter)
    {
    }
}
...
ObjectFactory.With<Parameter>(parameter).GetInstance<Controller>()

This will automatically pass the provided parameter to the constructor, which is very nice for passing around state / model objects. This gives some really nice possibilities in the infrastructure layer, where instances are requested from the DI container. In my ApplicationShell class I can now have something like this:

public void GoTo<TController, TParameter>(TParameter Parameter) where TController: IController
{
    TController controller = ObjectFactory.With(Parameter).GetInstance<TController>();
    SwitchToView(controller.View);
    controller.Initialize();
 }

So in order to e.g. pass a Sale object from a SaleController to PaymentController it’s simply:

public class SaleController
{
    private Sale _currentSale;

    public void RequestPayment()
    {
        _applicationShell.GoTo<PaymentController, Sale>(_currentSale);
    }
}

Last but not least, StructureMap now also supports AutoMocking. It’s still a little bit rough around the edges, but with some very small modifications (basically to use DynamicMocks by default), I could make it usable for me.

[TestFixture]
public class A_ReportSelectionController_with_some_reports :
  AutoMockingTestFixture<ReportSelectionController>
{
    private ReportSelectionController _controller;
    private List<ReportDefinition> _listOfReports;

    [SetUp]
    public override void SetUp()
    {
        base.SetUp();
        _controller = AutoMocker.CreatePartialMocked();
        AutoMocker.BackToRecordAll();
        _listOfReports = SetUpSampleReports();
        SetupResult.For(Service<IReportsConfiguration>()
         .GetReportDefinitions()).Return(_listOfReports);
    }

    [Test]
    public void Should_run_the_selected_report()
    {
        using (AutoMocker.Record())
        {
            Service<IApplicationShell>().GoTo<ReportController>(_listOfReports[1]);
        }

        using (AutoMocker.Playback())
        {
            _controller.Initialize();
            _controller.SelectReport(1);
            _controller.RunSelectedReport();
        }
    }
}

public class AutoMockingTestFixture<T> where T: class
{
    private RhinoAutoMocker<T> _autoMocker;

    [SetUp]
    public virtual void SetUp()
    {
        _autoMocker = new RhinoAutoMocker<T>();
    }

    protected RhinoAutoMocker<T> AutoMocker
    {
        get { return _autoMocker; }
    }

    protected TService Service<TService>()
    {
        return _autoMocker.Service<TService>();
    }
}

All in all: StructureMap’s new features make it a really nice product coming with less DLL’s than a full blown Castle Windsor DI ;-) Thanks Jeremy!

UPDATE: Jeremy just changed the AutoMocker to use DynamicMock by default

Published on 12/02/2008 at 16:33 by , tags , , , ,

Powered by Publify | Photo Startup stock photos