And it just got cooler. After I read this “BuildUp” Existing Objects with StructureMap I got an aha moment. The BuildUp function that was recently added just solved my very ugle winforms usercontrol problem. I use to have to add objectfactory.getinstance code in the constructors to get my dependencies just to keep the designer happy. I hate to design winforms without the designer but the designer hates me. But now this love hate relationship has bcome a little more livable. And all this because of Jeremy Miller. Thank you Jeremy once again.

What you are about to see is called C#. I know you’re not used to it from me but I will translate it to VB.Net this weekend. I promise.

I did not harm any real forms for this little example but I hope this proofs my point just as well.

Let’s take this case. A form has 2 usercontrols. Each usercontrol has a dependecy on a certain service.

Lets start with the services. These are pretty simple. I also made some interfaces to go with them.

C#
1
2
3
4
5
6
7
8
9
10
11
12
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.Services
{
    public interface IService1
    {
        String Test { get; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.Services
{
    public interface IService1
    {
        String Test { get; }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.Services
{
    public interface IService2
    {
        String Test { get; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.Services
{
    public interface IService2
    {
        String Test { get; }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.Services
{
    public class Service1 : Services.IService1
    {
        public string Test
        {
            get { return "service1"; }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.Services
{
    public class Service1 : Services.IService1
    {
        public string Test
        {
            get { return "service1"; }
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.Services
{
    public class Service2 : Services.IService2
    {
        public string Test
        {
            get { return "service2"; }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.Services
{
    public class Service2 : Services.IService2
    {
        public string Test
        {
            get { return "service2"; }
        }
    }
}

As you can see when service1 is initialized it will return service1, service2 will return service2.

So then I made a usercontrol baseclass.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace Structuremaptrial.View.Controls
{
    public partial class Basecontrol : UserControl
    {
        public Basecontrol()
        {
            InitializeComponent();
 
            StructureMap.ObjectFactory.BuildUp(this);
        }
    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Structuremaptrial.View.Controls
{
    public partial class Basecontrol : UserControl
    {
        public Basecontrol()
        {
            InitializeComponent();

            StructureMap.ObjectFactory.BuildUp(this);
        }
    }
}

This one, and only this one ;-). contains the buidlup method that does all the magic.

And then I made two very simple usercontrols.

C#
1
2
3
4
5
6
7
8
9
10
11
12
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.View.Controls
{
    public class UserControl1 : Basecontrol
    {
        public Services.IService1 Service{ get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.View.Controls
{
    public class UserControl1 : Basecontrol
    {
        public Services.IService1 Service{ get; set; }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.View.Controls
{
    public class UserControl2 : Basecontrol
    {
        public Services.IService2 Service { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.View.Controls
{
    public class UserControl2 : Basecontrol
    {
        public Services.IService2 Service { get; set; }
    }
}

As you can see Usercontrol1 needs service1 and Usercontrol2 needs service2.

As you can see there is no initialisation code for the services. Nowhere.

And then it’s time for the form.

I also interfaced that.

C#
1
2
3
4
5
6
7
8
9
10
11
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.View.Forms
{
    public interface IForm1
    {
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.View.Forms
{
    public interface IForm1
    {
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.View.Forms
{
    public class Form1 : IForm1
    {
        public Form1()
        {
            View.Controls.UserControl1 UserControl1 = new View.Controls.UserControl1();
            View.Controls.UserControl2 UserControl2 = new View.Controls.UserControl2();
            Console.WriteLine(UserControl1.Service.Test);
            Console.WriteLine(UserControl2.Service.Test); 
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.View.Forms
{
    public class Form1 : IForm1
    {
        public Form1()
        {
            View.Controls.UserControl1 UserControl1 = new View.Controls.UserControl1();
            View.Controls.UserControl2 UserControl2 = new View.Controls.UserControl2();
            Console.WriteLine(UserControl1.Service.Test);
            Console.WriteLine(UserControl2.Service.Test); 
        }
    }
}

As you can see no initialization for the service here either. But I do call them to print the text. So all logic tell us that a terrible nullreferenceexception will fall upon us. Shame on us.

But not to worry.

First we do some structuremap magic and initialize it.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial.IoC
{
    public class Configure
    {
        public void Setup()
        {
            StructureMap.ObjectFactory.Initialize(x =>
            {
 
                x.ForRequestedType<Services.IService1>().TheDefault.Is.OfConcreteType<Services.Service1>();
                x.ForRequestedType<Services.IService2>().TheDefault.Is.OfConcreteType<Services.Service2>();
                x.ForRequestedType<View.Forms.IForm1>().TheDefault.Is.OfConcreteType<View.Forms.Form1>();
                x.SetAllProperties(y =>
                {
                    y.OfType<Services.IService1>();
                    y.OfType<Services.IService2>();
                });
            }
            );
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial.IoC
{
    public class Configure
    {
        public void Setup()
        {
            StructureMap.ObjectFactory.Initialize(x =>
            {

                x.ForRequestedType<Services.IService1>().TheDefault.Is.OfConcreteType<Services.Service1>();
                x.ForRequestedType<Services.IService2>().TheDefault.Is.OfConcreteType<Services.Service2>();
                x.ForRequestedType<View.Forms.IForm1>().TheDefault.Is.OfConcreteType<View.Forms.Form1>();
                x.SetAllProperties(y =>
                {
                    y.OfType<Services.IService1>();
                    y.OfType<Services.IService2>();
                });
            }
            );
        }
    }
}

As you can see I use the SetAllProperties so that structuremap knows that when it encounters this properties it needs to fill them. And that is what BuildUp does.

And now I want to spike what I have there.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Structuremaptrial
{
    class Program
    {
        static void Main(string[] args)
        {
            var conf = new IoC.Configure();
            conf.Setup();
            var form1 = StructureMap.ObjectFactory.GetInstance<View.Forms.IForm1>();
            Console.ReadLine();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Structuremaptrial
{
    class Program
    {
        static void Main(string[] args)
        {
            var conf = new IoC.Configure();
            conf.Setup();
            var form1 = StructureMap.ObjectFactory.GetInstance<View.Forms.IForm1>();
            Console.ReadLine();
        }
    }
}

Which as you will see if you run this will give you this.

Ain’t it purdy? I think that says it all.

This was fun ;-).