|
From: <jer...@us...> - 2009-01-11 22:43:15
|
Revision: 219
http://structuremap.svn.sourceforge.net/structuremap/?rev=219&view=rev
Author: jeremydmiller
Date: 2009-01-11 22:43:11 +0000 (Sun, 11 Jan 2009)
Log Message:
-----------
adding TryGet****** to IContext/BuildSession
Modified Paths:
--------------
trunk/Source/HTML/ConstructorAndSetterInjection.htm
trunk/Source/HTML/UsingSessionContext.htm
trunk/Source/StructureMap/BuildSession.cs
trunk/Source/StructureMap/Container.cs
trunk/Source/StructureMap/PipelineGraph.cs
trunk/Source/StructureMap.Testing/BuildSessionTester.cs
trunk/Source/StructureMap.Testing/BuildUpIntegratedTester.cs
trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj
Added Paths:
-----------
trunk/Source/StructureMap.Testing/Examples/BuildUp.cs
Modified: trunk/Source/HTML/ConstructorAndSetterInjection.htm
===================================================================
--- trunk/Source/HTML/ConstructorAndSetterInjection.htm 2009-01-11 21:16:13 UTC (rev 218)
+++ trunk/Source/HTML/ConstructorAndSetterInjection.htm 2009-01-11 22:43:11 UTC (rev 219)
@@ -61,7 +61,8 @@
<!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;}??\fs20 \cf3 public\cf0 GreaterThanRule()\par ?? \{\par ?? \}\par ??\par ?? \cf3 public\cf0 GreaterThanRule(\cf3 string\cf0 Attribute, \cf3 int\cf0 Value)\par ?? \{\par ?? _Attribute = Attribute;\par ?? _Value = Value;\par ?? \}}
-->
- <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
+ <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"
+ class="code-sample">
<p style="margin: 0px;">
<span style="color: blue;">public</span>
GreaterThanRule()</p>
@@ -107,7 +108,8 @@
<!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;}??\fs20 [\cf3 DefaultConstructor\cf0 ]\par ?? \cf4 public\cf0 DataSession(\cf3 IDatabaseEngine\cf0 database)\par ?? : \cf4 this\cf0 (database,\par ?? \cf4 new\cf0 \cf3 CommandFactory\cf0 (database),\par ?? \cf4 new\cf0 \cf3 AutoCommitExecutionState\cf0 (database.GetConnection(), database.GetDataAdapter()),\par ?? \cf4 new\cf0 \cf3 TransactionalExecutionState\cf0 (database.GetConnection(), database.GetDataAdapter()))\par ?? \{\par ?? \}}
-->
- <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
+ <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"
+ class="code-sample">
<p style="margin: 0px;">
[<span style="color: #2b91af;">DefaultConstructor</span>]</p>
<p style="margin: 0px;">
@@ -386,7 +388,7 @@
<span style="color: #2b91af;">Rule</span>[] Rules { <span style="color: blue;">
get</span>; <span style="color: blue;">set</span>; }</p>
<p style="margin: 0px;">
-& }</p>
+ }</p>
</div>
<!--EndFragment-->
<p>I can explicitly configure what gets injected into the "Rule" property for a
@@ -555,8 +557,192 @@
<hr />
<h2>Applying Setter Injection to an Existing Object (BuildUp)</h2>
- <p>asdf</p>
- <hr />
+ <p>Many times you simply cannot control when an object is going to be created
+ (ASP.Net WebForms), but you may still want to inject dependencies and even
+ primitive values into an already constructed object. To fill this gap,
+ StructureMap 2.5.2+ introduces the "BuildUp()" method on Container and
+ ObjectFactory. BuildUp() works by finding the default Instance for the
+ concrete type passed into the BuildUp() method (or create a new Instance if one
+ does not already exist), then applying any setters from that Instance
+ configuration. At this time, StructureMap does not apply interception
+ inside of BuildUp().</p>
+ <p>Let's say that we have a class called "BuildTarget1" like
+ this:</p>
+<!--
+{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 BuildUpTarget1\par ??\cf0 \{\par ?? \cf3 public\cf0 \cf4 IGateway\cf0 Gateway \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf4 IService\cf0 Service \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}}
+-->
+ <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;">
+ <p style="margin: 0px;">
+ <span style="color: blue;">public</span> <span style="color: blue;">class</span>
+ <span style="color: #2b91af;">BuildUpTarget1</span></p>
+ <p style="margin: 0px;">
+ {</p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">public</span>
+ <span style="color: #2b91af;">IGateway</span> Gateway {
+ <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</p>
+ <p style="margin: 0px;">
+ }</div>
+<p>In usage, we'd like to have the Gateway dependency injected into a new instance of the BuildTarget1 class when we call BuildUp():</p>
+<!--
+{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red0\green128\blue0;}??\fs20 [\cf3 Test\cf0 ]\par ?? \cf4 public\cf0 \cf4 void\cf0 create_a_setter_rule_and_see_it_applied_in_BuildUp_through_ObjectFactory()\par ?? \{\par ?? \cf4 var\cf0 theGateway = \cf4 new\cf0 \cf3 DefaultGateway\cf0 ();\par ?? \cf3 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.IgnoreStructureMapConfig = \cf4 true\cf0 ;\par ?? x.ForRequestedType<\cf3 IGateway\cf0 >().TheDefault.IsThis(theGateway);\par ?? \par ?? \cf5 // First we create a new Setter Injection Policy that\par ??\cf0 \cf5 // forces StructureMap to inject all public properties\par ??\cf0 \cf5 // where the PropertyType is IGateway\par ??\cf0 x.SetAllProperties(y =>\par ?? \{\par ?? y.OfType<\cf3 IGateway\cf0 >();\par ?? \});\par ?? \});\par ??\par ?? \cf5 // Create an instance of BuildUpTarget1\par ??\cf0 \cf4 var\cf0 target = \cf4 new\cf0 \cf3 BuildUpTarget1\cf0 ();\par ??\par ?? \cf5 // Now, call BuildUp() on target, and\par ??\cf0 \cf5 // we should see the Gateway property assigned\par ??\cf0 \cf3 ObjectFactory\cf0 .BuildUp(target);\par ??\par ?? target.Gateway.ShouldBeTheSameAs(theGateway);\par ?? \}}
+-->
+ <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;">
+ <p style="margin: 0px;">
+ [<span style="color: #2b91af;">Test</span>]</p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">public</span>
+ <span style="color: blue;">void</span>
+ create_a_setter_rule_and_see_it_applied_in_BuildUp_through_ObjectFactory()</p>
+ <p style="margin: 0px;">
+ {</p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">
+ var</span> theGateway = <span style="color: blue;">new</span>
+ <span style="color: #2b91af;">DefaultGateway</span>();</p>
+ <p style="margin: 0px;">
+ <span style="color: #2b91af;">
+ ObjectFactory</span>.Initialize(x =></p>
+ <p style="margin: 0px;">
+ {</p>
+ <p style="margin: 0px;">
+
+ x.ForRequestedType<<span style="color: #2b91af;">IGateway</span>>().TheDefault.IsThis(theGateway);</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+
+ <span style="color: green;">// First we create a new Setter Injection Policy
+ that</span></p>
+ <p style="margin: 0px;">
+
+ <span style="color: green;">// forces StructureMap to inject all public
+ properties</span></p>
+ <p style="margin: 0px;">
+
+ <span style="color: green;">// where the PropertyType is IGateway</span></p>
+ <p style="margin: 0px;">
+
+ x.SetAllProperties(y =></p>
+ <p style="margin: 0px;">
+ {</p>
+ <p style="margin: 0px;">
+
+ y.OfType<<span style="color: #2b91af;">IGateway</span>>();</p>
+ <p style="margin: 0px;">
+ });</p>
+ <p style="margin: 0px;">
+ });</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+ <span style="color: green;">
+ // Create an instance of BuildUpTarget1</span></p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">
+ var</span> target = <span style="color: blue;">new</span>
+ <span style="color: #2b91af;">BuildUpTarget1</span>();</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+ <span style="color: green;">
+ // Now, call BuildUp() on target, and</span></p>
+ <p style="margin: 0px;">
+ <span style="color: green;">
+ // we should see the Gateway property assigned</span></p>
+ <p style="margin: 0px;">
+ <span style="color: #2b91af;">
+ ObjectFactory</span>.BuildUp(target);</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+
+ target.Gateway.ShouldBeTheSameAs(theGateway);</p>
+ <p style="margin: 0px;">
+ }</p>
+ </div>
+<!--EndFragment-->
+<p>BuildUp() also works with primitive properties (but I'm not sure how useful this
+ will really be):</p>
+<!--
+{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 ClassThatHasConnection\par ??\cf0 \{\par ?? \cf3 public\cf0 \cf3 string\cf0 ConnectionString \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}\par ??\par ?? [\cf4 TestFixture\cf0 ]\par ?? \cf3 public\cf0 \cf3 class\cf0 \cf4 demo_the_BuildUp\par ??\cf0 \{\par ?? [\cf4 Test\cf0 ]\par ?? \cf3 public\cf0 \cf3 void\cf0 push_in_a_string_property()\par ?? \{\par ?? \cf5 // There is a limitation to this. As of StructureMap 2.5.2,\par ??\cf0 \cf5 // you can only use the .WithProperty().EqualTo() syntax\par ??\cf0 \cf5 // for BuildUp()\par ??\cf0 \cf5 // SetProperty() will not work at this time.\par ??\cf0 \cf3 var\cf0 container = \cf3 new\cf0 \cf4 Container\cf0 (x =>\par ?? \{\par ?? x.ForConcreteType<\cf4 ClassThatHasConnection\cf0 >().Configure\par ?? .WithProperty(o => o.ConnectionString).EqualTo(\cf6 "connect1"\cf0 );\par ??\par ?? \});\par ??\par ?? \cf3 var\cf0 @class = \cf3 new\cf0 \cf4 ClassThatHasConnection\cf0 ();\par ?? container.BuildUp(@class);\par ??\par ?? @class.ConnectionString.ShouldEqual(\cf6 "connect1"\cf0 );\par ?? \}\par ?? \}}
+-->
+ <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;">
+ <p style="margin: 0px;">
+ <span style="color: blue;">public</span> <span style="color: blue;">class</span>
+ <span style="color: #2b91af;">ClassThatHasConnection</span></p>
+ <p style="margin: 0px;">
+ {</p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">public</span>
+ <span style="color: blue;">string</span> ConnectionString {
+ <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</p>
+ <p style="margin: 0px;">
+ }</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+ [<span style="color: #2b91af;">TestFixture</span>]</p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">public</span> <span style="color: blue;">class</span>
+ <span style="color: #2b91af;">demo_the_BuildUp</span></p>
+ <p style="margin: 0px;">
+ {</p>
+ <p style="margin: 0px;">
+ [<span style="color: #2b91af;">Test</span>]</p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">public</span>
+ <span style="color: blue;">void</span> push_in_a_string_property()</p>
+ <p style="margin: 0px;">
+ {</p>
+ <p style="margin: 0px;">
+ <span style="color: green;">
+ // There is a limitation to this. As of StructureMap 2.5.2,</span></p>
+ <p style="margin: 0px;">
+ <span style="color: green;">
+ // you can only use the .WithProperty().EqualTo() syntax</span></p>
+ <p style="margin: 0px;">
+ <span style="color: green;">
+ // for BuildUp()</span></p>
+ <p style="margin: 0px;">
+ <span style="color: green;">
+ // SetProperty() will not work at this time.</span></p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">
+ var</span> container = <span style="color: blue;">new</span>
+ <span style="color: #2b91af;">Container</span>(x =></p>
+ <p style="margin: 0px;">
+ {</p>
+ <p style="margin: 0px;">
+
+ x.ForConcreteType<<span style="color: #2b91af;">ClassThatHasConnection</span>>().Configure</p>
+ <p style="margin: 0px;">
+
+ .WithProperty(o => o.ConnectionString).EqualTo(<span style="color: #a31515;">"connect1"</span>);</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+ });</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+ <span style="color: blue;">
+ var</span> @class = <span style="color: blue;">new</span>
+ <span style="color: #2b91af;">ClassThatHasConnection</span>();</p>
+ <p style="margin: 0px;">
+ container.BuildUp(@class);</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+
+ @class.ConnectionString.ShouldEqual(<span style="color: #a31515;">"connect1"</span>);</p>
+ <p style="margin: 0px;">
+ }</p>
+ <p style="margin: 0px;">
+ }</p>
+ </div>
+<!--EndFragment-->
+<hr />
<h2><a name="SetterPolicies"></a>Creating Policies for Setter Injection</h2>
<p>New in StructureMap 2.5.2+ is the ability to create setter injection policies.
What this means is that you create conventions to define which public setter
Modified: trunk/Source/HTML/UsingSessionContext.htm
===================================================================
--- trunk/Source/HTML/UsingSessionContext.htm 2009-01-11 21:16:13 UTC (rev 218)
+++ trunk/Source/HTML/UsingSessionContext.htm 2009-01-11 22:43:11 UTC (rev 219)
@@ -15,7 +15,7 @@
dependencies that will be used within that object request. The IContext
interface is shown below:</p>
<!--
-{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red128\green128\blue128;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IContext\par ??\cf0 \{\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Gets a reference to the \cf5 <see cref="BuildStack">\cf6 BuildStack\cf5 </see>\cf6 for this build session\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 BuildStack\cf0 BuildStack \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 The concrete type of the immediate parent object in the object graph\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 Type\cf0 ParentType \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Get the object of type T that is valid for this build session.\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <typeparam name="T"></typeparam>\par ??\cf0 \cf5 ///\cf6 \cf5 <returns></returns>\par ??\cf0 T GetInstance<T>();\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Gets the root "frame" of the object request\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 BuildFrame\cf0 Root \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 The requested instance name of the object graph\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf3 string\cf0 RequestedName \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Register a default object for the given PluginType that will\par ??\cf0 \cf5 ///\cf6 be used throughout the rest of the current object request\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <param name="pluginType"></param>\par ??\cf0 \cf5 ///\cf6 \cf5 <param name="defaultObject"></param>\par ??\cf0 \cf3 void\cf0 RegisterDefault(\cf4 Type\cf0 pluginType, \cf3 object\cf0 defaultObject);\par ?? \}}
+{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red128\green128\blue128;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IContext\par ??\cf0 \{\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Gets a reference to the \cf5 <see cref="BuildStack">\cf6 BuildStack\cf5 </see>\cf6 for this build session\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 BuildStack\cf0 BuildStack \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 The concrete type of the immediate parent object in the object graph\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 Type\cf0 ParentType \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Get the object of type T that is valid for this build session.\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <typeparam name="T"></typeparam>\par ??\cf0 \cf5 ///\cf6 \cf5 <returns></returns>\par ??\cf0 T GetInstance<T>();\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Get the object of type T that is valid for this build session by name.\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <typeparam name="T"></typeparam>\par ??\cf0 \cf5 ///\cf6 \cf5 <returns></returns>\par ??\cf0 T GetInstance<T>(\cf3 string\cf0 name);\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Gets the root "frame" of the object request\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 BuildFrame\cf0 Root \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 The requested instance name of the object graph\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf3 string\cf0 RequestedName \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Register a default object for the given PluginType that will\par ??\cf0 \cf5 ///\cf6 be used throughout the rest of the current object request\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <param name="pluginType"></param>\par ??\cf0 \cf5 ///\cf6 \cf5 <param name="defaultObject"></param>\par ??\cf0 \cf3 void\cf0 RegisterDefault(\cf4 Type\cf0 pluginType, \cf3 object\cf0 defaultObject);\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Same as GetInstance, but can gracefully return null if \par ??\cf0 \cf5 ///\cf6 the Type does not already exist\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <typeparam name="T"></typeparam>\par ??\cf0 \cf5 ///\cf6 \cf5 <returns></returns>\par ??\cf0 T TryGetInstance<T>() \cf3 where\cf0 T : \cf3 class\cf0 ;\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Same as GetInstance(name), but can gracefully return null if \par ??\cf0 \cf5 ///\cf6 the Type and name does not already exist\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <typeparam name="T"></typeparam>\par ??\cf0 \cf5 ///\cf6 \cf5 <param name="name"></param>\par ??\cf0 \cf5 ///\cf6 \cf5 <returns></returns>\par ??\cf0 T TryGetInstance<T>(\cf3 string\cf0 name) \cf3 where\cf0 T : \cf3 class\cf0 ;\par ?? \}}
-->
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;">
<p style="margin: 0px;">
@@ -81,6 +81,28 @@
style="color: green;"> </span><span style="color: gray;"><summary></span></p>
<p style="margin: 0px;">
<span style="color: gray;">///</span><span
+ style="color: green;"> Get the object of type T that is valid for this build
+ session by name.</span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"></summary></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><typeparam
+ name="T"></typeparam></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><returns></returns></span></p>
+ <p style="margin: 0px;">
+ T GetInstance<T>(<span style="color: blue;">string</span>
+ name);</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><summary></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
style="color: green;"> Gets the root "frame" of the object request</span></p>
<p style="margin: 0px;">
<span style="color: gray;">///</span><span
@@ -131,10 +153,71 @@
RegisterDefault(<span style="color: #2b91af;">Type</span> pluginType,
<span style="color: blue;">object</span> defaultObject);</p>
<p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><summary></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> Same as GetInstance, but can gracefully return null
+ if </span>
+ </p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> the Type does not already exist</span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"></summary></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><typeparam
+ name="T"></typeparam></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><returns></returns></span></p>
+ <p style="margin: 0px;">
+ T TryGetInstance<T>() <span style="color: blue;">
+ where</span> T : <span style="color: blue;">class</span>;</p>
+ <p style="margin: 0px;">
+ </p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><summary></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> Same as GetInstance(name), but can gracefully return
+ null if </span>
+ </p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> the Type and name does not already exist</span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"></summary></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><typeparam
+ name="T"></typeparam></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><param
+ name="name"></param></span></p>
+ <p style="margin: 0px;">
+ <span style="color: gray;">///</span><span
+ style="color: green;"> </span><span style="color: gray;"><returns></returns></span></p>
+ <p style="margin: 0px;">
+ T TryGetInstance<T>(<span style="color: blue;">string</span>
+ name) <span style="color: blue;">where</span> T : <span style="color: blue;">
+ class</span>;</p>
+ <p style="margin: 0px;">
}</p>
</div>
<!--EndFragment-->
<!--
+{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red128\green128\blue128;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IContext\par ??\cf0 \{\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Gets a reference to the \cf5 <see cref="BuildStack">\cf6 BuildStack\cf5 </see>\cf6 for this build session\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 BuildStack\cf0 BuildStack \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 The concrete type of the immediate parent object in the object graph\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 Type\cf0 ParentType \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Get the object of type T that is valid for this build session.\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <typeparam name="T"></typeparam>\par ??\cf0 \cf5 ///\cf6 \cf5 <returns></returns>\par ??\cf0 T GetInstance<T>();\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Gets the root "frame" of the object request\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 BuildFrame\cf0 Root \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 The requested instance name of the object graph\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf3 string\cf0 RequestedName \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Register a default object for the given PluginType that will\par ??\cf0 \cf5 ///\cf6 be used throughout the rest of the current object request\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <param name="pluginType"></param>\par ??\cf0 \cf5 ///\cf6 \cf5 <param name="defaultObject"></param>\par ??\cf0 \cf3 void\cf0 RegisterDefault(\cf4 Type\cf0 pluginType, \cf3 object\cf0 defaultObject);\par ?? \}}
+-->
+<!--EndFragment-->
+<!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red128\green128\blue128;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IContext\par ??\cf0 \{\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Gets a reference to the \cf5 <see cref="BuildStack">\cf6 BuildStack\cf5 </see>\cf6 for this build session\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 BuildStack\cf0 BuildStack \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 The concrete type of the immediate parent object in the object graph\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 Type\cf0 ParentType \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Get the object of type T that is valid for this build session.\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf5 ///\cf6 \cf5 <typeparam name="T"></typeparam>\par ??\cf0 \cf5 ///\cf6 \cf5 <returns></returns>\par ??\cf0 T GetInstance<T>();\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 Gets the root "frame" of the object request\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf4 BuildFrame\cf0 Root \{ \cf3 get\cf0 ; \}\par ??\par ?? \cf5 ///\cf6 \cf5 <summary>\par ??\cf0 \cf5 ///\cf6 The requested instance name of the object graph\par ??\cf0 \cf5 ///\cf6 \cf5 </summary>\par ??\cf0 \cf3 string\cf0 RequestedName \{ \cf3 get\cf0 ; \}\par ?? \}}
-->
<!--EndFragment-->
Modified: trunk/Source/StructureMap/BuildSession.cs
===================================================================
--- trunk/Source/StructureMap/BuildSession.cs 2009-01-11 21:16:13 UTC (rev 218)
+++ trunk/Source/StructureMap/BuildSession.cs 2009-01-11 22:43:11 UTC (rev 219)
@@ -27,6 +27,13 @@
T GetInstance<T>();
/// <summary>
+ /// Get the object of type T that is valid for this build session by name.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ T GetInstance<T>(string name);
+
+ /// <summary>
/// Gets the root "frame" of the object request
/// </summary>
BuildFrame Root { get; }
@@ -43,6 +50,23 @@
/// <param name="pluginType"></param>
/// <param name="defaultObject"></param>
void RegisterDefault(Type pluginType, object defaultObject);
+
+ /// <summary>
+ /// Same as GetInstance, but can gracefully return null if
+ /// the Type does not already exist
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ T TryGetInstance<T>() where T : class;
+
+ /// <summary>
+ /// Same as GetInstance(name), but can gracefully return null if
+ /// the Type and name does not already exist
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="name"></param>
+ /// <returns></returns>
+ T TryGetInstance<T>(string name) where T : class;
}
public class BuildSession : IContext
@@ -105,6 +129,11 @@
return (T) CreateInstance(typeof (T));
}
+ public T GetInstance<T>(string name)
+ {
+ return (T) CreateInstance(typeof (T), name);
+ }
+
BuildFrame IContext.Root
{
get { return _buildStack.Root; }
@@ -182,7 +211,24 @@
_defaults[pluginType] = defaultObject;
}
+ public T TryGetInstance<T>() where T : class
+ {
+ if (_defaults.Has(typeof(T)))
+ {
+ return (T) _defaults[typeof (T)];
+ }
+ return _pipelineGraph.HasDefaultForPluginType(typeof (T))
+ ? ((IContext) this).GetInstance<T>()
+ : null;
+ }
+
+ public T TryGetInstance<T>(string name) where T : class
+ {
+ return _pipelineGraph.HasInstance(typeof (T), name) ? ((IContext) this).GetInstance<T>(name) : null;
+ }
+
+
private IInstanceFactory forType(Type pluginType)
{
return _pipelineGraph.ForType(pluginType);
Modified: trunk/Source/StructureMap/Container.cs
===================================================================
--- trunk/Source/StructureMap/Container.cs 2009-01-11 21:16:13 UTC (rev 218)
+++ trunk/Source/StructureMap/Container.cs 2009-01-11 22:43:11 UTC (rev 219)
@@ -228,7 +228,7 @@
/// <returns></returns>
public object TryGetInstance(Type pluginType, string instanceKey)
{
- return _pipelineGraph.ForType(pluginType).FindInstance(instanceKey) == null
+ return !_pipelineGraph.HasInstance(pluginType, instanceKey)
? null
: GetInstance(pluginType, instanceKey);
}
@@ -240,7 +240,7 @@
/// <returns></returns>
public object TryGetInstance(Type pluginType)
{
- return !_pipelineGraph.PluginTypes.Any(p => p.PluginType == pluginType)
+ return !_pipelineGraph.HasDefaultForPluginType(pluginType)
? null
: GetInstance(pluginType);
}
Modified: trunk/Source/StructureMap/PipelineGraph.cs
===================================================================
--- trunk/Source/StructureMap/PipelineGraph.cs 2009-01-11 21:16:13 UTC (rev 218)
+++ trunk/Source/StructureMap/PipelineGraph.cs 2009-01-11 22:43:11 UTC (rev 219)
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using StructureMap.Diagnostics;
using StructureMap.Graph;
using StructureMap.Pipeline;
@@ -206,5 +207,16 @@
return list;
}
+
+ public bool HasDefaultForPluginType(Type pluginType)
+ {
+ PluginTypeConfiguration configuration = PluginTypes.FirstOrDefault(p => p.PluginType == pluginType);
+ return configuration == null ? false : configuration.Default != null;
+ }
+
+ public bool HasInstance(Type pluginType, string instanceKey)
+ {
+ return ForType(pluginType).FindInstance(instanceKey) != null;
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap.Testing/BuildSessionTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/BuildSessionTester.cs 2009-01-11 21:16:13 UTC (rev 218)
+++ trunk/Source/StructureMap.Testing/BuildSessionTester.cs 2009-01-11 22:43:11 UTC (rev 219)
@@ -187,6 +187,61 @@
session.CreateInstance(typeof (IGateway));
});
}
+
+ [Test]
+ public void when_retrieving_with_try_get_instance_for_instance_that_does_not_exists()
+ {
+ var session = new BuildSession(new PluginGraph());
+ session.TryGetInstance<IService>().ShouldBeNull();
+ }
+
+ [Test]
+ public void when_retrieving_by_try_get_instance_for_instance_that_does_exist()
+ {
+ var session = new BuildSession();
+ var theService = new ColorService("red");
+ session.RegisterDefault(typeof(IService), theService);
+
+ session.TryGetInstance<IService>().ShouldBeTheSameAs(theService);
+ }
+
+ [Test]
+ public void when_retrieving_by_try_get_named_instance_that_does_not_exist()
+ {
+ var session = new BuildSession();
+ session.TryGetInstance<IService>("red").ShouldBeNull();
+ }
+
+ [Test]
+ public void when_retrieving_by_try_get_named_instance_that_does_exist()
+ {
+ var red = new ColorService("red");
+ var green = new ColorService("green");
+
+ PluginGraph graph = new PluginGraph();
+ PluginFamily family = graph.FindFamily(typeof(IService));
+ family.AddInstance(new LiteralInstance(red).WithName("red"));
+ family.AddInstance(new LiteralInstance(green).WithName("green"));
+
+ var session = new BuildSession(graph);
+ session.TryGetInstance<IService>("red").ShouldBeTheSameAs(red);
+ session.TryGetInstance<IService>("green").ShouldBeTheSameAs(green);
+ }
+
+ [Test]
+ public void when_retrieving_an_object_by_name()
+ {
+ var red = new ColorService("red");
+ var green = new ColorService("green");
+
+ PluginGraph graph = new PluginGraph();
+ PluginFamily family = graph.FindFamily(typeof(IService));
+ family.AddInstance(new LiteralInstance(red).WithName("red"));
+ family.AddInstance(new LiteralInstance(green).WithName("green"));
+
+ var session = new BuildSession(graph);
+ session.GetInstance<IService>("red").ShouldBeTheSameAs(red);
+ }
}
public interface IClassWithRule
Modified: trunk/Source/StructureMap.Testing/BuildUpIntegratedTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/BuildUpIntegratedTester.cs 2009-01-11 21:16:13 UTC (rev 218)
+++ trunk/Source/StructureMap.Testing/BuildUpIntegratedTester.cs 2009-01-11 22:43:11 UTC (rev 219)
@@ -57,13 +57,21 @@
{
x.IgnoreStructureMapConfig = true;
x.ForRequestedType<IGateway>().TheDefault.IsThis(theGateway);
+
+ // First we create a new Setter Injection Policy that
+ // forces StructureMap to inject all public properties
+ // where the PropertyType is IGateway
x.SetAllProperties(y =>
{
y.OfType<IGateway>();
});
});
+ // Create an instance of BuildUpTarget1
var target = new BuildUpTarget1();
+
+ // Now, call BuildUp() on target, and
+ // we should see the Gateway property assigned
ObjectFactory.BuildUp(target);
target.Gateway.ShouldBeTheSameAs(theGateway);
Added: trunk/Source/StructureMap.Testing/Examples/BuildUp.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Examples/BuildUp.cs (rev 0)
+++ trunk/Source/StructureMap.Testing/Examples/BuildUp.cs 2009-01-11 22:43:11 UTC (rev 219)
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace StructureMap.Testing.Examples
+{
+ public class ClassThatHasConnection
+ {
+ public string ConnectionString { get; set; }
+ }
+
+ [TestFixture]
+ public class demo_the_BuildUp
+ {
+ [Test]
+ public void push_in_a_string_property()
+ {
+ // There is a limitation to this. As of StructureMap 2.5.2,
+ // you can only use the .WithProperty().EqualTo() syntax
+ // for BuildUp()
+ // SetProperty() will not work at this time.
+ var container = new Container(x =>
+ {
+ x.ForConcreteType<ClassThatHasConnection>().Configure
+ .WithProperty(o => o.ConnectionString).EqualTo("connect1");
+
+ });
+
+ var @class = new ClassThatHasConnection();
+ container.BuildUp(@class);
+
+ @class.ConnectionString.ShouldEqual("connect1");
+ }
+ }
+}
Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj
===================================================================
--- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-01-11 21:16:13 UTC (rev 218)
+++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-01-11 22:43:11 UTC (rev 219)
@@ -222,6 +222,7 @@
<Compile Include="Examples.cs">
<SubType>Form</SubType>
</Compile>
+ <Compile Include="Examples\BuildUp.cs" />
<Compile Include="Examples\CustomInstance.cs" />
<Compile Include="Examples\Interception.cs" />
<Compile Include="Examples\RegisteringWithTheAPI.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|