Ryan LanciauxNew Media Mercenary

Very Quick and Simple Dependency Injection with StructureMap

February 26, 2008 by ryan

There are a lot of resources on the web about dependency injection and using StructureMap, however, I wanted to write something that was an extremely simple example. This is basically the tip of the iceberg but hopefully it will help someone. 

We want to make our application very loosely coupled -- to achieve this 'loose coupling' we're going to have several projects in the solution. What this means if we need to change any part of this application later on (we wouldn't want to in this case since its a demo and all), we could do so without impacting everything else. Anyways, we're going to create three class libraries and a WinForms application.

Next we want to create our main inteface -- this will be under the DisplayMessage Project:

 

namespace DisplayMessage

{

    public interface IDisplayMessage

    {

        string message();

    }

}

The interface defines just one method that, when implemented, will return a string stating what class its coming from. Next, we want to create our two implementation classes (one under Implementation1, the other under Implementation2). Please keep in mind I'm not suggesting to have every class in it's own library -- it's just for the sake of example :)

Implementation1:

    public class MessageOne : IDisplayMessage

    {

        public string message()

        {

            return "This is a message from Implementation1";

        }

    }

 Implementation2:

    public class MessageTwo : IDisplayMessage

    {

        public string message()

        {

            return "This is a message from Implementation2";

        }

    }

Okay that was easy enough, now on to the Forms App.  We're first going to add a reference to StructureMap and the project DisplayMessage and create a file called StructureMap.config -- this config file is going to define all of our assemblies. We want to make sure we edit the properties of this file and set the Copy to Output Directory option to "Copy Always." StructureMap will use this file at runtime to get our object references. The config file looks like this: 

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

<StructureMap>

  <Assembly Name="DisplayMessage" />

  <Assembly Name="Implementation1" />

  <Assembly Name="Implementation2" />

 

  <PluginFamily Type="DisplayMessage.IDisplayMessage"

                Assembly="DisplayMessage"

                DefaultKey="MessageOne">

    <Plugin Type="Implementation1.MessageOne"

            Assembly="Implementation1"         

            ConcreteKey="MessageOne" />

    <Plugin Type="Implementation2.MessageTwo"

                Assembly="Implementation2"

                ConcreteKey="MessageTwo" />   

  </PluginFamily>

</StructureMap>

Notice we define a PluginFamily for the IDisplayMessage interface and set the default implementation to be MessageOne (the DefaultKey of PluginFamily references the ConcreteKey of the Plugin). Other than that, this should be pretty straight-forward but if you have any confusion, please check out the StructureMap documentation. Only a couple more things to do before we can run this...

Ok, we're going to add 3 buttons to our form -- one for the default IDisplayMessage and one for each implementation.

 Now to add the code...

        //Default IDisplayMessage 

        private void btnDefault_Click(object sender, EventArgs e)

        {

            IDisplayMessage msg = StructureMap.ObjectFactory.GetInstance<IDisplayMessage>();

            System.Windows.Forms.MessageBox.Show(msg.message());

        }

 

        //Implementation1

        private void btnOne_Click(object sender, EventArgs e)

        {

            IDisplayMessage msg = StructureMap.ObjectFactory.GetNamedInstance<IDisplayMessage>("MessageOne");

            System.Windows.Forms.MessageBox.Show(msg.message());

        }

 

        //Implementation2

        private void btnTwo_Click(object sender, EventArgs e)

        {

            IDisplayMessage msg = StructureMap.ObjectFactory.GetNamedInstance<IDisplayMessage>("MessageTwo");

            System.Windows.Forms.MessageBox.Show(msg.message());

        } 

Lets parse this up a little bit...

  • IDisplayMessage msg = StructureMap.ObjectFactory.GetInstance<IDisplayMessage>();

    This statement gets the default IDisplayMessage object in the StructureMap.config file. Currently, it will get the same object as getting a named instance of "MessageOne"
  • IDisplayMessage msg = StructureMap.ObjectFactory.GetNamedInstance<IDisplayMessage>("MessageOne");

    This statement gets the object associated with the ConcreteKey "MessageOne"
  • IDisplayMessage msg = StructureMap.ObjectFactory.GetNamedInstance<IDisplayMessage>("MessageTwo");

    This statement gets the object associated with the ConcreteKey "MessageTwo"

Instead of simply hitting F5, we will need to build the application -- we want to copy the DLL files from Implementation1 and Implementation2 to the bin directory of the forms app and run the executable there.  For testing, however, we can add a reference to both projects (this completely defeats the purpose of dependency injection so be sure to remove the references later on) or adjust the output directory of the implementation class libraries to be the same as the Form application's bin directory. Running the application shows that everything is working as expected.

For more information please check out the following links:

kick it on DotNetKicks.com



Learning a new Language

February 24, 2008 by ryan

I'm currently in the process of getting to be more comfortable with Ruby on Rails and really just starting to learn F#. In both cases, simply reading a book or tutorials and following along has not been enough to really get my head around it.

First off, I've decided I have to have a project or something to work against. For RoR, there's a little site I'm working on (more on that some other time) -- For F#, I'm currently working thru the 99 Problems with my brother (you can see our solutions here).  When simply reading a book or tutorials you don't generally come accrossed the same kind of road blocks that you would find in a project. I think overcoming the road blocks is what helps me better understand a language.

All that being said, I think it's truly important to read as many books, tutorials and source code as you can. Authors read to become better writers ... as developers we should too (See Justice Gray's blog for more on this). I have this bad habit of thinking in C#/Java/C++; this is pretty much as bad as it would be for me to try and speak Japanese using a English to Japanese dictionary. Seeing how other people code helps me stay away from that. 

What are some steps that you take when you start learning a new language? 

kick it on DotNetKicks.com


Tags: , ,
Categories: Development
Actions: E-mail | Kick it! | Permalink | commentComments (6) | RSS comment feedComment RSS


The DotNetKicks Effect

February 12, 2008 by ryan

After starting this website as a real blog just a couple of weeks ago, any number of visitors has been extremely welcome. I was very happy to have about 30 unique hits a day with hope that, over time, others will find this site useful. Recently, however, I posted a link to a color theme for visual studio on dotnetkicks. That post made it to the front page and eventually generated way more traffic than I ever imagined that it would...




I realize for some people 1000 hits in a couple of days is nothing but I was shocked to see that kind of traffic from dotnetkicks, especially for a Visual Studio 2008 Theme.



Break down of page views.


Graph of my average of 30 or so hits a day up to a peak of about 700 back down to 70s-80s.

Needless to say, DotNetKicks has a lot more visitors than I thought it did. I wonder what kind of traffic volume people receive for a more globally useful posting...

kick it on DotNetKicks.com


Diving into Ruby on Rails

February 6, 2008 by ryan

This past weekend I started really digging into Ruby on Rails.  For a while now, I have known a little bit of ruby (by reading Why's Poignant Guide and messing around a little with Rails), however, I wanted to have a much stronger understanding in it -- even if it's only for the concepts. 

 
Why Rails -- Why Now?

Rails has been publicly available since July 2004; some may ask why I am just now becoming interested in the framework. There are actually several main reasons...

  1. It is a good educational resource in the MVC Pattern. This applies to many implementations such as Microsoft MVC, Symfony and Cake on PHP and a whole slew of other frameworks.
  2. Rails is becoming a more viable option with JRuby and the forthcoming releases of IronRuby.
  3. The concept of DB Migrations is very nice -- especially when you have encountered the difficulty involved in placing your database under source control.

 

Setting up the environment

  1. I needed to configure my computer to run the rails apps. NetBeans seemed like a good idea to me because of the simple JRuby integration (other options Aptana Studio, Eclipse, your favorite text editor w/ Instant rails). 
  2. I already had MySql installed on my computer so there was no need to set up a database server (Sqlite was a tempting option as well).
  3. Created a series of databases (as needed) for the various test rails apps to write to.
  4. Downloaded and installed MySqlYog Community edition. I knew I was going to be handling most of my database stuff with the Rails ActiveRecord implementation and db migrations BUT I still wanted to see what was going on inside the db.

 

Initial Impressions

After the initial hour or so of setting up my environment, I wrote some quick test applications (following some tutorials, at first obviously). I really liked the principle of Convention over Configuration.  This was apparent in many areas of the framework such as the generator / rake tools and the easy application configuration in the .yaml files. I can see how this may not be the best choice for certain applications but for a lot of web applications, it seems like it will be a good fit.






© 2008 Ryan Lanciaux :: powered by BlogEngine.NET