Jeremy D. Miller -- The Shade Tree Developer

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Introduction to using StructureMap for Dependency Injection

StructureMap is an open source tool I’ve written for Dependency Injection support in .Net.  This past week I’ve had a couple requests for a gentle introduction to StructureMap, so here’s my first attempt.  Typically I use StructureMap in a handful of ways:

 

  1. Configuration and creation of services (little “s”) that my code depends upon.  By service here I don’t necessarily mean SOA and web services, but web service proxy classes are an automatic candidate for StructureMap configuration.  I’m referring to subsystems of your application like logging modules, persistence, gateways to other systems, or really anything that you don’t want your code to be tightly coupled to.
  2. Object composition.  Code reuse and unit testing is easier when you favor composition over inheritance relationships, but composition implies that you need to some mechanical coding work just to put the object graph together.  This is where StructureMap comes into play.
  3. Plugin support.  Occasionally there is a real need for pluggable, extensible application frameworks.

 

 

A Contrived Example

 

Let’s say you’re an integration developer in a shop with a crazily mixed bag of applications floating around a big central database.  You want to write a pluggable infrastructure for batch scheduling little integration tasks.  You may need to pull data by a sql query, a stored procedure, or by opening a file – then do something with the data.  All you really know is that the possible sources of the data and the actions on the data will change over time.  You might decide to create a pluggable framework using StructureMap to handle the configuration (Okay, in reality you would probably buy something off of the shelf or utilize DTS out of the box, but I needed an example).

 

First off, let’s ignore the configuration schema and concentrate on defining a set of interfaces and roles for our “Trigger” framework.  The main interface will be this:

 

      public interface ITrigger

      {

            // Do whatever it is that you do

            void Execute();

 

            // Tell me when you want to run next

            DateTime NextExecutionTime();

      }

 

Configuring the most basic trigger class will define the mechanism to retrieve the data, an action to perform on the data, and a strategy for determining the next run time (next Monday, the top of the next hour, the last day of the month, etc.).  That adds the following code:

 

      [Pluggable("Basic")] // Tell StructureMap that it "builds" this class and that it's alias is "Basic"

      public class Trigger : ITrigger

      {

            private readonly IScheduler _scheduler;

            private readonly IDataSource _source;

            private readonly IAction _action;

 

            public Trigger(IScheduler scheduler, IDataSource source, IAction action)

            {

                  _scheduler = scheduler;

                  _source = source;

                  _action = action;

            }

 

            public void Execute()

            {

                  DataTable table = _source.FetchTable();

                  _action.Process(table);

            }

 

            public DateTime NextExecutionTime()

            {

                  return _scheduler.GetNextRunTime(DateTime.Now);

            }

      }

 

      public interface IDataSource

      {

            DataTable FetchTable();

      }

 

      public interface IAction

      {

            void Process(DataTable table);

      }

 

      public interface IScheduler

      {

            DateTime GetNextRunTime(DateTime currentTime);

      }

 

The first Trigger that we’re going to need to build is going to daily run a SQL query against the central database, and then email the results to an unlucky support person for resolution.  First we create the little classes for the scheduling, data source, and the action.

 

      [Pluggable("SQL")]

      public class SqlDataSource : IDataSource

      {

            private readonly string _sql;

            private readonly IDatabase _database;

 

            public SqlDataSource(IDatabase database, string sql)

            {

                  _sql = sql;

                  _database = database;

            }

 

            public DataTable FetchTable()

            {

                  return _database.FetchDataTable(_sql);

            }

      }

 

      [Pluggable("Email")]

      public class EmailAction : IAction

      {

            public EmailAction(string to, string body){…}

            public void Process(DataTable table){…}

      }

 

      [Pluggable("Daily")]

      public class DailyScheduler : IScheduler

      {

            public DailyScheduler(){}

            public DateTime GetNextRunTime(DateTime currentTime){…}

      }

 

SqlDataSource itself depends upon the IDatabase interface that provides access to an underlying database and handles the raw ADO.Net manipulation.  Let’s say that the central database is a Sql Server database (but I’m starting to miss good old reliable Oracle).  That adds the following to the code:

 

      public interface IDatabase

      {

            DataTable FetchDataTable(string sql);

            void SetStoredProcedureName(string storedProcedureName);

            void SetParameter(string parameterName, object parameterValue);

            DataTable FetchDataTableFromStoredProcedure();

      }

 

      public class SqlDatabase : IDatabase {…}

 

Okay, now we can finally make our StructureMap configuration to create the object graph for our first Trigger.  The first thing we need to do is create a file named “StructureMap.config” that will be copied to the application directory.  At a minimum, we need to define four things for StructureMap:

 

  1. <Assembly> - The .Net assemblies to scan for possible interfaces and classes to be built by StructureMap
  2. <PluginFamily> - The .Net types that can be requested from StructureMap.  In our case this would be the ITrigger, IDataSource, IAction, and IScheduler interfaces.  It can also be abstract or concrete classes as well.
  3. <Plugin> - The concrete .Net types that will implement the interfaces of the PluginFamily types.
  4. <Instance> - The actual object graph configurations.  Notice that we didn’t do anything special in our classes to enable StructureMap (except the [Pluggable] attributes).  All you need to do to enable your class to be configured by StructureMap is to take in all dependencies and properties in a constructor function.  StructureMap also supports “Setter Injection,” but that’s really just meant for Types that aren’t under your control.

 

Jumping into the StructureMap.config file we’ll first configure the default IDatabase instance to point to the central Sql Server database.

 

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

<StructureMap>

      <!-- Tell StructureMap to scan the StructureMapSample.dll assembly for possible PluginFamily's and Plugin's -->

      <Assembly Name="StructureMapSample" />

     

      <!-- Define a PluginFamily for IDatabase, making the default instance "CentralDatabase" -->

      <PluginFamily Assembly="StructureMapSample" Type="StructureMapSample.IDatabase" DefaultKey="CentralDatabase">

            <!-- Tell StructureMap that the SqlDatabase class is a plugin to IDatabase called "MicrosoftSqlServer" -->

            <Plugin Assembly="StructureMapSample" Type="StructureMapSample.SqlDatabase" ConcreteKey="MicrosoftSqlServer"/>

           

            <!-- Configure the "CentralDatabase" instance of IDatabase.  The <Property> nodes define the arguments to the constructor

            functions -->

            <Instance Key="CentralDatabase" Type="MicrosoftSqlServer">

                  <Property Name="connectionString" Value="connection string to somewhere..."/>

            </Instance>

      </PluginFamily>

</StructureMap>

 

With this configuration we could at anytime in our code type IDatabase database = (IDatabase) ObjectFactory.GetInstance(typeof(IDatabase)); to get a configured instance of the SqlDatabase class with the connection string set.  If the database changed to Oracle or DB2 later, only the configuration to create a different concrete IDatabase class would be changed (yeah right).  In this case I defined the Plugin explicitly in the XML configuration.  The [Pluggable(“My Plugin Alias”)] attribute is an equivalent mechanism to using the <Plugin> node.  I prefer the attributes wherever possible, but some people feel differently. 

 

Moving on to the first Trigger instance, we would add a <PluginFamily> node for ITrigger and an <Instance> node for the object graph for the first Trigger.

 

      <PluginFamily Assembly="StructureMapSample" Type="StructureMapSample.ITrigger">

            <!-- Create a BasicTrigger object, and give it a DailyScheduler, -->

            <!-- Uses the public Trigger(IScheduler scheduler, IDataSource source, IAction action) constructor function -->

            <Instance Type="Basic" Key="MyFirstTrigger">

           

                  <!-- DailyScheduler -->

                  <Property Name="scheduler" Type="Daily" />

                 

                  <!-- SqlDataSource(IDatabase database, string sql) -->

                  <!-- By leaving off an explicit definition for "database" StructureMap will use the default

                       "CentralDatabase" instance -->

                  <Property Name="source" Type="SQL">

                        <Property Name="sql" Value="select * from errorlog"/>

                  </Property>

                 

                  <!-- public EmailAction(string to, string body) -->

                  <Property Name="action" Type="Email">

                        <Property Name="to" Value="poorfool@helpdesk.company.com"/>

                        <Property Name="body" Value="Fix these now!" />

                  </Property>

            </Instance>

      </PluginFamily>

 

The Trigger framework can now create this instance by calling into StructureMap as something like this:

 

            public void RunTriggers()

            {

                  string[] triggersToRun = this.findTriggersToRun();

 

                  foreach (string triggerName in triggersToRun)

                  {

                        // Ask StructureMap to build the object instance

                        ITrigger trigger =

                              (ITrigger) ObjectFactory.GetNamedInstance(typeof(ITrigger), triggerName);

 

                        trigger.Execute();

                        DateTime nextTime = trigger.NextExecutionTime();

 

                        this.rescheduleTrigger(triggerName, nextTime);

                  }

            }

 

Additional trigger’s could be created by simply configuring the object graphs into the StructureMap.config file as a new <Instance> node.  The big advantage in this case is that StructureMap can quite happily accommodate any new classes that you create later to implement the ITrigger/IDataSource/IAction interfaces.  You could even “plugin” all new assemblies to be used by your application without recompilation.  That’s potentially a huge win for my company because of the sheer number of per client customizations that we have to do.

 

There is far more information and an actual schema document at http://structuremap.sourceforge.net.  I threw this together in a hurry, so please let me know if this is useful or if something else is necessary to make the tool more clear.  Sometime in the near-ish future I’ll post much more on some of the new capabilities for configuration management and environment testing that we’re building into StructureMap for complex build and staging scenarios.


Posted 11-18-2005 8:39 AM by Jeremy D. Miller
Filed under:

[Advertisement]

Comments

Jeremy D. Miller -- The Shade Tree Developer wrote More Thoughts on Model View Presenter
on 02-16-2006 1:18 AM
This is a follow up to my post on the Model View Presenter pattern with ASP.Net to address or clarify...
Jeremy D. Miller -- The Shade Tree Developer wrote More Thoughts on Model View Presenter
on 02-16-2006 9:22 AM
Author: &lt;a href=&quot;blogs/jeremy.miller&quot;&gt;Jeremy D. Miller&lt;/a&gt;&lt;br /&gt;Carlton commented that the Presenter class looks a lot like the Gang of Four &quot;Mediator&quot; pattern. He's absolutely right. Something to keep in mind when learning to apply design patterns is that a class or group of classes can easily be an instance of more than one pattern. In this case &quot;Presenter&quot; or &quot;Controller&quot; is just a more specific name for a class within a larger structural pattern.
Jeremy D. Miller -- The Shade Tree Developer wrote Things we talked about at the Austin Code Camp
on 03-06-2006 8:32 AM
This past Saturday was the Austin Code Camp.&amp;nbsp; I had a great time and the general consensus was that...
Yi wrote re: Introduction to using StructureMap for Dependency Injection
on 07-06-2006 2:44 PM
It's really nice framework! I am going to use it in my project.
Yi wrote re: Introduction to using StructureMap for Dependency Injection
on 07-06-2006 3:07 PM
A quick question about ObjectFactory.GetInstance(typeof(IDatabase));.

Does the OjbectFactory caches the instance or it reads the configuration file and search the assembly every time GetInstance is called?
Jeremy D. Miller wrote re: Introduction to using StructureMap for Dependency Injection
on 07-06-2006 3:19 PM
Yi,

Not quite either.  Unless you explicitly specify the Scope property ObjectFactory.GetInstance() will return a new instance per request.

StructureMap largely caches the configuration.  Scanning assemblies and parsing the StructureMap.config file only happens once on the first call to ObjectFactory (unless you force the issue with ObjectFactory.ResetDefaults()).

Jeremy
Yi wrote re: Introduction to using StructureMap for Dependency Injection
on 07-06-2006 5:04 PM
Thanks Jeremy! So by default, ObjectFactory creates new instance for each request. However, it reads config file and scans assemblies only once. I also find what you just said in the documentation:
"New in version 1.0 is the ability to quickly define different creation modes.  This functionality can be configured with the new optional "Scope" property on the [PluginFamily] attribute or the "Scope" attribute on the <PluginFamily> node."

I just put in an Authentication Plugin for my project. I was kind of curious if StructureMap will increase the memory usage. I barely notice the difference. Very nice work! :)
Jeremy D. Miller -- The Shade Tree Developer wrote Slides from the StructureMap Talk Last Night at ADNUG
on 07-11-2006 10:52 AM
The slide deck and sample code from my StructureMap talk last night is available from the ADNUG downloads...
Yi wrote re: Introduction to using StructureMap for Dependency Injection
on 07-27-2006 2:57 PM
Hello Jeremy,

I wonder where I can find XSD file for the StructureMap.

Thanks!

Yi
Jeremy D. Miller wrote re: Introduction to using StructureMap for Dependency Injection
on 07-27-2006 4:13 PM
Yi,

I've never made one.  Some of the nodes and attributes are dynamic, so it's not really going to be possible anyway.

Sorry,

Jeremy
Yi wrote re: Introduction to using StructureMap for Dependency Injection
on 07-27-2006 4:36 PM
Interesting. Can you give me an example about these "dynamic nodes and attributes"? Thank you in advance!

Yi
Daniel Essin wrote re: Introduction to using StructureMap for Dependency Injection
on 09-17-2006 7:50 PM

I'm very impressed with the work that you've done on StructureMap. I know that I need something like this that allows a degree of abstraction, but I've always been a bit challenged by higher math so I'm having a hard time absorbing all the fine points. I've got a couple of questions that you perhaps could help me with.

First off, I want to mention that in order to run the StructureMap Explorer under .net 2.0 you need to as a [STAThread] attribute to the main or an exception is thrown when trying to create the browser component.

I'm sure that you're familiar with sharpDevelop. I am trying to do something like that - create a platform for my apps that will provide all of the basic services such as encryption, authentication, logging, etc. and into which all of the application-specific forms and functions will "plug in"

I've studied the possibilty of simply using the sharpDevelop shell and replacing all of the content, using Spring.NET or using StructureMap. I've also looked as SAF (Simple application framework) by chen.

I have stepped through the code in sharpDevelop dozens of times and I understand what it is doing pretty well but their external xl config files are so complex that every time I try to alter one the whole thing breaks. My opinion of that platform is that without a gui utility to examine your assemblies and write the .addin files, it will probably never work for me.

I like the feature in Spring.NET of being able to embed the config for each assembly in a resurce and extract it during the load. This reduces the possibility that the config file will get lost, corrupted or damaged by a user trying to alter its behavior. For the same reason I like the idea of being able to accomplish the configuration of StructureMap by applying attributes to the classes.

Am I correct in my understanding that what you have done in the StructureMap  Explorer app is to have accomplished the entire configuation with attributes and that is why there is no .config file for the app?

Becaus I am abstractionally challenged, I would appreciate it if you could give me some guidance about how to best have assemblies contribute items to the menubar,child forms that are invoked or affected by selecting different tree nodes (like in your explorer, and how I can osilate all of the commands that are executed in one place so the can be invoked form either a menu, form event or a use typing a command at a prompt?

Thanks,

Dan Essin (essin@ieee.org)

Jeremy D. Miller wrote re: Introduction to using StructureMap for Dependency Injection
on 09-17-2006 9:16 PM

Dan,

The STAThread is a known issue, and if you'll give me a little while I'll get an example up showing how to use StructureMap sans config file to do exactly what you're trying to do.

Jeremy

Daniel Essin wrote re: Introduction to using StructureMap for Dependency Injection
on 09-18-2006 5:12 PM

That would be great. Thanks.

Yi wrote re: Introduction to using StructureMap for Dependency Injection
on 12-07-2006 2:26 PM

Hello Jeremy,

I just dropped an email to your yahoo mail. I encountered some issue when using StructureMap with Windows Service. The .NET runtime complains that "System.Runtime.Serialization.SerializationException: Unable to find assembly 'StructureMap, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'." I double-checked that the structuremap.dll is in the working dir.

I wonder if you used StructureMap with Windows Service. I hope you can shed me some light on this one.

Thanks!!!

Yi

Suresh wrote re: Introduction to using StructureMap for Dependency Injection
on 01-03-2007 3:16 AM

Hai Jeremy,

I have a doubt in my application for using StructureMap.

Can you tel me actually usage is like a Factory pattern.

Is it right??

In my application i got the instance of a Concrete class, it has more than 10 subclasses with the usage of n number of XmlSchema ( object). But the XmlSchema are use used in the different n number of Concrete classes..

if i want to do any changes in one schema in one Concrete class that also depends on the n-1th concrete class ( Object dependency exists here.. ). can u tel me,  can i use Structure map container, is it helpful for me...

else can you tel me which pattern is optimal one..

i need help

my mail id is : vasuresh@jeevantechnologies.com

Thanks

Suresh

Jeremy D. Miller -- The Shade Tree Developer wrote StructureMap 2.0 is Released! Inversion of Control and Dependency Injection for .Net 2.0
on 04-02-2007 10:28 AM

It took long enough, and I&#39;ve had a pretty good stream of people asking for this, so here it is:

kasajian wrote re: Introduction to using StructureMap for Dependency Injection
on 12-15-2007 9:22 PM

I got my hands dirty and learned DI/IoC by studying the crystalproject.org API.  I found Simone Busoli's introduction to it on dotnetslackers.com to be one of the best introductions on DI, if not one of the best articles written in general.

So now understand it and am quite impressed with the cleanness of the crystal implementation.  My plan was to study the other DI packages out there and then do a comparison, but frankly, when I start to go down the path of learning ObjectBuilder and even StructureMap, I quickly lose interest because the introductions start out more complex and convoluted than what crystal offers.  I realize that I'm probably not being as fair to the other frameworks, but as many of us having relatively limited time, it seems as though there ought to be a better for people to decide between the different frameworks.  There out to be a comparison article that  does justice to the existing frameworks.

Another thing that's missing is that the DI introductions I've seen thus far focus on the programmatic use of the APIs, which some people prefer.  But I strongly believe that the configuration based method has a lot more value.  It would be good to have an introductory article to each of the DI frameworks for those shops that are planning on configuring the containers using external files and minimize the attributes and APIs in the code.

Thank you for listening. :)

DotNetKicks.com wrote IoC with StructureMap
on 01-25-2008 4:22 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Ryan Lanciaux wrote Very Quick and Simple Dependency Injection with StructureMap
on 02-27-2008 12:22 AM

Very Quick and Simple Dependency Injection with StructureMap

VusCode - Coding dreams since 1998! wrote Design for testability - Structure map (Part 6)
on 03-03-2008 4:59 AM

On my quest to design for testability, I&#39;ve already covered: Part 1 - Separation of concerns (SOC

Scott Hanselman's Computer Zen wrote List of .NET Dependency Injection Containers (IOC)
on 03-14-2008 1:15 AM
ASPInsiders wrote List of .NET Dependency Injection Containers (IOC)
on 03-14-2008 2:18 AM

I'm trying to expand my mind around dependency injection in .NET (beyond the two frameworks I've personally

AllenWang.NET wrote List of .NET Dependency Injection Containers (IOC)
on 04-02-2008 9:53 PM
Itzik Kasovitch wrote re: Introduction to using StructureMap for Dependency Injection
on 06-01-2008 7:02 AM

Is it possible to add components manually to structure map's object factory? For example I want to create some object manually and the add it to structure map like it is done in WindsorContainer using AddComponent.

Jeremy D. Miller wrote re: Introduction to using StructureMap for Dependency Injection
on 06-01-2008 10:21 AM

@Itzik,

With 2.0, ObjectFactory.InjectStub<T>(T object);

With the 2.5 trunk, the above still works, but there are far more options.

ObjectFactory.Inject<T>(T object);

Itzik Kasovitch wrote re: Introduction to using StructureMap for Dependency Injection
on 06-02-2008 10:55 AM

I have checked out structuremap from sourceforge and tried to run the build script. Unfortunately, it failes. It seems that some files are missing. Should I make some settings to be able to run the build successfully. If so, where are the guidelines?

ms440 wrote re: Introduction to using StructureMap for Dependency Injection
on 06-10-2008 10:26 PM

Hi Jeremy,

I've used the StructureMap 1.0 in one of my prev project.

After watching the screencast that you and Rob Conery put together last week, I realized that I'd like to get back to StructureMap in my new project (not ASP.NET MVC) again. Two questions though:

First, during the screencast you've promised to put together some documentation for 2.5. What's the ETA for that? Would I be able to use it within my application project timeframe (I'll have to make a decision about the use of StructureMap before the end of June :(.

Second, I checked out the code for 2.5 and couldn't compile it (as with Itzik Kasovitch case). Could you please take a look into the problem he's discovered?

Third and most important! Thanks a lot for your excellent and extremely useful work on patterns in general (congrats on your MSDN article - pure pleasure to read) and StructureMap in particular.

Cliff wrote re: Introduction to using StructureMap for Dependency Injection
on 06-15-2008 12:07 AM

Is it possible to use StructureMap to map types across projects without having a reference?  For example, if you have three projects: web (references model), model, and data (references model) can you in the web project set up a mapping from an interface in the Model project to a concrete type in the Data project, without having a project reference to data from web?

Jeremy D. Miller wrote re: Introduction to using StructureMap for Dependency Injection
on 06-18-2008 10:59 PM

@Cliff,

Yes, but watch your build procedures.  You'll have to pull that off in the Xml, or create a completely new assembly that references all three of the other assemblies just to hold the STructureMap configuration.  One way or another, StructureMap has to be able to load any assembly through the normal mechanisms.  You'll have to copy around the assemblies yourself instead of depending upon VS to do it for you.

Baka.Blog wrote Using StuctureMap for dependency injection
on 11-11-2008 5:44 AM

StructureMap is an open source Inversion of Control (IOC) tool by Jeremy Miller written for dependency

What’s in your wallet? – Part 2 | iLude wrote What&rsquo;s in your wallet? &ndash; Part 2 | iLude
on 03-01-2009 2:31 PM

Pingback from  What&rsquo;s in your wallet? &ndash; Part 2 | iLude

Add a Comment

(required)  
(optional)
(required)  
Remember Me?