CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

Using StructureMap 2.5 to inject your Entity objects into Services

Forget the neverending argument on the ALT.NET list about whether or not it’s acceptable to inject services into an Entity object (for the record, I say “no way”).  What if you want to go the other way around?  What if you want to request a service or a view or a command of some kind and have an Entity injected into the service/view/command?  You’ve now got (at least) 2 ways to do that in StructureMap.

 

If you already have the Entity

If you’ve already got the Entity you want, you “pass” the Entity object into ObjectFactory (or an IContainer).  Let’s say you have a view named TradeView like this:

 

    public class TradeView : IView

    {

        private readonly Trade _trade;

 

        public TradeView(Trade trade)

        {

            _trade = trade;

        }

 

        public Trade Trade

        {

            get { return _trade; }

        }

    }

If you already have the Trade object in memory, you can grab the IView that displays the Trade by using the Container.With().GetInstance<T>() methods:

        [Test]

        public void Example()

        {

            IContainer container = new Container();

            Trade theTrade = new Trade();

 

            var view = container.With<Trade>(theTrade).GetInstance<TradeView>();

 

            view.Trade.ShouldBeTheSameAs(theTrade);

        }

The “explicit arguments” to GetInstance<T>() will be propogated all the way through the object graph.  Let’s say we have a class named Command that takes in an IView, a Trade, and a Node object in its constructor.  The actual object passed to the Command constructor might be a TradeNode class that, surprise, needs a Trade object as well.  An elided version of these classes is shown below:

    public class Command

    {

        public Command(Trade trade, Node node, IView view)

        {

        }

    }

 

    public class TradeNode : Node

    {

        public TradeNode(Trade trade)

        {

        }

    }

When we request an instance of the Command class using a known Trade object, all of the classes (Command itself, TradeView, and TradeNode) that need a Trade object in their constructor would get the Trade object we specified in …With<Trade>(theTrade)… below:

        [Test]

        public void Explicit_services_are_used_throughout_the_object_graph()

        {

            var theTrade = new Trade();

 

            IContainer container = new Container(r =>

            {

                r.ForRequestedType<IView>().TheDefaultIsConcreteType<TradeView>();

                r.ForRequestedType<Node>().TheDefaultIsConcreteType<TradeNode>();

            });

 

            Command command = container.With<Trade>(theTrade).GetInstance<Command>();

 

            command.Trade.ShouldBeTheSameAs(theTrade);

            command.Node.IsType<TradeNode>().Trade.ShouldBeTheSameAs(theTrade);

            command.View.IsType<TradeView>().Trade.ShouldBeTheSameAs(theTrade);

        }

 

If you had more than one IView that displayed a Trade object, you could also do this:

 

        [Test]

        public void pass_explicit_service_into_all_instances()

        {

            // The Container is constructed with 2 instances

            // of TradeView

            var container = new Container(r =>

            {

                r.ForRequestedType<TradeView>()

                    .TheDefaultIsConcreteType<TradeView>()

                    .AddConcreteType<SecuredTradeView>();

            });

 

            Trade theTrade = new Trade();

 

            var views = container.With<Trade>(theTrade).GetAllInstances<TradeView>();

 

            views[0].Trade.ShouldBeTheSameAs(theTrade);

            views[1].Trade.ShouldBeTheSameAs(theTrade);

        }

 

and have the known Trade object passed into every instance of TradeView.

 

I’ll post the other way to do this tonight….



Comments

Torkel said:

This is a really useful feature, I discovered it (and the need for it) a while ago in Castle Windsor.

# September 25, 2008 5:12 PM

Dew Drop – September 26, 2008 | Alvin Ashcraft's Morning Dew said:

Pingback from  Dew Drop &ndash; September 26, 2008 | Alvin Ashcraft's Morning Dew

# September 26, 2008 8:43 AM

Jonathan said:

When you refer to a "service", you're talking about an "Application Service", right? Per my reading of Evan's DDD a "Domain Service" is just as much a part of the domain as anything else and can be called from within the domain “core”.

Case in point: Suppose you had a really complicated interest calculation mechanism in your LoanAccount entity and you wanted to use the same mechanism in your InterestAccount entity, wouldn't it make sense to inject the service into both in order to "stay DRY".

# September 26, 2008 12:03 PM

Jeremy D. Miller said:

@Jonathon,

I was thinking much more in general than DDD in terms of "anything you would not want to new() up directly.:  

Not that you could have possibly known this, but the staggering amount of jargon in DDD is a huge pet peeve of mine.

"Domain Service" vs "Application Service" might have some useful differentiation, but the jargon still bugs me.

"Case in point: Suppose you had a really complicated interest calculation mechanism in your LoanAccount entity and you wanted to use the same mechanism in your InterestAccount entity, wouldn't it make sense to inject the service into both in order to "stay DRY"."

I wouldn't bother with SM for this kind of thing.  Just pass the LoanAccount and InterestAccount into the domain service as it's invoked is my bet.

# September 26, 2008 2:07 PM

David Hayden said:

Jeremy,

Has 2.5 been released yet? I keep seeing reference to 2.5 but only see 2.4.9 for download. Just want to make sure I am not using old bits. Hopefully 2.4.9 is production deployable because deployed she is :)

# September 26, 2008 4:24 PM

Jeremy D. Miller said:

@David,

2.5 is not yet released.  Jimmy Bogard has labeled it the Duke Nukem Forever release.

I've got to do more docs and clean up the API a touch.  

There will be very minor API changes from 2.4.9 to 2.5 in the registration

# September 26, 2008 4:58 PM

David Hayden said:

Thanks for the info, Jeremy!

Looking forward to the final release.

# October 1, 2008 11:47 AM

Jeremy D. Miller -- The Shade Tree Developer said:

The most general question I get with StructureMap is “how do I get started?” Personally, I’d recommend

# November 30, 2008 10:56 PM

Community Blogs said:

The most general question I get with StructureMap is “how do I get started?” Personally, I’d recommend

# November 30, 2008 11:48 PM

A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas said:

Pingback from  A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas

# December 2, 2008 10:16 AM

A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas said:

Pingback from  A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas

# December 3, 2008 11:04 AM

A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas said:

Pingback from  A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas

# December 4, 2008 11:09 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeremy D. Miller

Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy previously worked as a systems architect building mission critical supply chain software for a Fortune 100 company and learned agile development practices as a .Net consultant at ThoughtWorks, one of the pioneers of agile development. Jeremy is the author of the open source StructureMap (http://structuremap.sourceforge.net) tool for Dependency Injection with .Net and the forthcoming StoryTeller (http://storyteller.tigris.org) tool for supercharged FIT testing in .Net. Jeremy's thoughts on just about everything software related can be found on his weblog "The Shade Tree Developer" at http://codebetter.com/blogs/jeremy.miller, part of the popular CodeBetter site. Jeremy is a Microsoft MVP for C#. Check out Devlicio.us!

Our Sponsors

Proudly Partnered With


This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP