From: <jer...@us...> - 2008-08-07 20:23:13
|
Revision: 129 http://structuremap.svn.sourceforge.net/structuremap/?rev=129&view=rev Author: jeremydmiller Date: 2008-08-07 20:23:07 +0000 (Thu, 07 Aug 2008) Log Message: ----------- Optional Setter injection, some emitting performance optimization Modified Paths: -------------- trunk/Source/StructureMap/Emitting/ArgumentEmitter.cs trunk/Source/StructureMap/Emitting/BuildInstanceMethod.cs trunk/Source/StructureMap/Emitting/ClassBuilder.cs trunk/Source/StructureMap/Emitting/DynamicAssembly.cs trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs trunk/Source/StructureMap/Emitting/Parameters/ChildArrayParameterEmitter.cs trunk/Source/StructureMap/Emitting/Parameters/ChildParameterEmitter.cs trunk/Source/StructureMap/Emitting/Parameters/EnumParameterEmitter.cs trunk/Source/StructureMap/Emitting/Parameters/ParameterEmitter.cs trunk/Source/StructureMap/Emitting/Parameters/PrimitiveParameterEmitter.cs trunk/Source/StructureMap/Emitting/Parameters/StringParameterEmitter.cs trunk/Source/StructureMap/Graph/ITypeScanner.cs trunk/Source/StructureMap/Graph/Plugin.cs trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Building.cs trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Expressions.cs trunk/Source/StructureMap/Pipeline/ConfiguredInstance.cs trunk/Source/StructureMap/Pipeline/DefaultInstance.cs trunk/Source/StructureMap/Pipeline/IConfiguredInstance.cs trunk/Source/StructureMap/Pipeline/InstanceMementoPropertyReader.cs trunk/Source/StructureMap/ReflectionHelper.cs trunk/Source/StructureMap/StructureMap.csproj trunk/Source/StructureMap.Testing/Configuration/DSL/AddInstanceTester.cs trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs trunk/Source/StructureMap.Testing/Configuration/DSL/DeepInstanceTester.cs trunk/Source/StructureMap.Testing/Configuration/DefaultInstanceNodeTester.cs trunk/Source/StructureMap.Testing/Configuration/InlineInstanceDefinitionInProfileAndMachineNodesTester.cs trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs trunk/Source/StructureMap.Testing/Graph/EmittingTester.cs trunk/Source/StructureMap.Testing/Graph/PluginTester.cs trunk/Source/StructureMap.Testing/Graph/SetterInjectionEmittingTester.cs trunk/Source/StructureMap.Testing/InstanceMementoInstanceCreationTester.cs trunk/Source/StructureMap.Testing/Pipeline/ConfiguredInstanceTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj trunk/Source/StructureMap.Testing/StructureMap.config trunk/Source/StructureMap.Testing/TestData/Array.xml trunk/Source/StructureMap.Testing/TestData/AttributeNormalized.xml trunk/Source/StructureMap.Testing/TestData/Config1.xml trunk/Source/StructureMap.Testing/TestData/FullTesting.XML trunk/Source/StructureMap.Testing/TestData/ObjectMother.config trunk/Source/StructureMap.Testing/TestData/SampleConfig.xml trunk/Source/StructureMap.Testing/TestData/ShortInstance.xml trunk/Source/StructureMap.Testing/TestData/StructureMap.config trunk/Source/StructureMap.Testing.Widget/Hierarchy.cs trunk/Source/StructureMap.Testing.Widget/IWidget.cs trunk/Source/StructureMap.Testing.Widget/Rule.cs trunk/Source/StructureMap.Testing.Widget/StructureMap.Testing.Widget.csproj trunk/Source/StructureMap.Testing.Widget/WidgetMaker.cs trunk/Source/StructureMap.Testing.Widget2/EnumerationCheck.cs trunk/Source/StructureMap.Testing.Widget4/Strategy.cs trunk/Source/StructureMap.Testing.Widget5/WidgetRegistry.cs trunk/Source/StructureMap.sln trunk/StructureMap.config Added Paths: ----------- trunk/Source/HTML/Glossary.htm trunk/Source/StructureMap/ConfigurationClasses.cd trunk/Source/StructureMap/Emitting/Parameters/Methods.cs trunk/Source/StructureMap.DataAccess/Oracle/OracleDatabaseEngine.cs trunk/Source/StructureMap.Testing/Examples/ trunk/Source/StructureMap.Testing/Examples/QuickStart.cs trunk/Source/StructureMap.Testing/Pipeline/OptionalSetterInjectionTester.cs trunk/Source/StructureMap.Testing.Widget/BuilderSamples.cs Added: trunk/Source/HTML/Glossary.htm =================================================================== --- trunk/Source/HTML/Glossary.htm (rev 0) +++ trunk/Source/HTML/Glossary.htm 2008-08-07 20:23:07 UTC (rev 129) @@ -0,0 +1,311 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> + <head> + <title></title> + <style type="text/css"> + .style1 + { + font-family: "Courier New", Courier, monospace; + } + </style> + </head> + <body> + <h1>Glossary</h1> + <p>There are some terms that reoccur throughout the documentation and show up in the StructureMap configuration. Understanding these terms and how they relate to StructureMap isn't a prerequisite to using StructureMap, but it helps.</p> + <h4>Container</h4> + <p>Tools like StructureMap are generally referred to as IoC containers, or in the + Java world sometimes as "lightweight" containers to differentiate them from the + old EJB containers. As far as I know, the term Inversion of Control + Container was coined by members of the PicoContainer team at ThoughtWorks and + popularized by the publication of Martin Fowler's paper + <a href="http://martinfowler.com/articles/injection.html">Inversion of Control + Containers and the Dependency Injection</a> pattern in January 2004. + StructureMap development was already underway when the paper was published. + I was definitely influenced by the paper and PicoContainer itself to a degree, + but I resisted the term "Container" for a long time. StructureMap has a + container class, but it's always been largely hidden behind the static + ObjectFactory class. New in StructureMap 2.5 is an easy way to use the + Container without StructureMapConfiguration or ObjectFactory like this:</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;\red163\green21\blue21;\red0\green128\blue0;}??\fs20 \cf3 IContainer\cf0 container = \cf4 new\cf0 \cf3 Container\cf0 (registry =>\par ?? \{\par ?? registry.AddInstanceOf<\cf3 Rule\cf0 >().UsingConcreteType<\cf3 ARule\cf0 >().WithName(\cf5 "Alias"\cf0 );\par ??\par ?? \cf6 // Add an instance by specifying the ConcreteKey\par ??\cf0 registry.AddInstanceOf<\cf3 IWidget\cf0 >()\par ?? .UsingConcreteType<\cf3 ColorWidget\cf0 >()\par ?? .WithName(\cf5 "Purple"\cf0 )\par ?? .WithProperty(\cf5 "Color"\cf0 ).EqualTo(\cf5 "Purple"\cf0 );\par ??\par ?? \cf6 // Specify a new Instance, override a dependency with a named instance\par ??\cf0 registry.AddInstanceOf<\cf3 Rule\cf0 >().UsingConcreteType<\cf3 WidgetRule\cf0 >().WithName(\cf5 "RuleThatUsesMyInstance"\cf0 )\par ?? .Child<\cf3 IWidget\cf0 >(\cf5 "widget"\cf0 ).IsNamedInstance(\cf5 "Purple"\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: #2b91af;"> + IContainer</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>(registry =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + registry.AddInstanceOf<<span style="color: #2b91af;">Rule</span>>().UsingConcreteType<<span + style="color: #2b91af;">ARule</span>>().WithName(<span + style="color: #a31515;">"Alias"</span>);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Add an instance by specifying the ConcreteKey</span></p> + <p style="margin: 0px;"> + + registry.AddInstanceOf<<span style="color: #2b91af;">IWidget</span>>()</p> + <p style="margin: 0px;"> + + .UsingConcreteType<<span style="color: #2b91af;">ColorWidget</span>>()</p> + <p style="margin: 0px;"> + + .WithName(<span style="color: #a31515;">"Purple"</span>)</p> + <p style="margin: 0px;"> + + .WithProperty(<span style="color: #a31515;">"Color"</span>).EqualTo(<span + style="color: #a31515;">"Purple"</span>);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Specify a new Instance, override a dependency + with a named instance</span></p> + <p style="margin: 0px;"> + + registry.AddInstanceOf<<span style="color: #2b91af;">Rule</span>>().UsingConcreteType<<span + style="color: #2b91af;">WidgetRule</span>>().WithName(<span + style="color: #a31515;">"RuleThatUsesMyInstance"</span>)</p> + <p style="margin: 0px;"> + + .Child<<span style="color: #2b91af;">IWidget</span>>(<span + style="color: #a31515;">"widget"</span>).IsNamedInstance(<span + style="color: #a31515;">"Purple"</span>);</p> + <p style="margin: 0px;"> + });</p> + </div> +<!--EndFragment--> +<p> </p> + <h4>PluginType & PluggedType</h4> + <p>I use the term "PluginType" throughout the code and documentation to mean "the + type that you want." In my current project I have this line of + configuration:</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;}??\fs20 ForRequestedType<\cf3 IRepository\cf0 >().TheDefaultIsConcreteType<\cf3 Repository\cf0 >().CacheBy(\cf3 InstanceScope\cf0 .Hybrid);} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">IRepository</span>>().TheDefaultIsConcreteType<<span + style="color: #2b91af;">Repository</span>>().CacheBy(<span + style="color: #2b91af;">InstanceScope</span>.Hybrid);</p> + </div> +<!--EndFragment--> +<p>If you request an object of <span class="style1">IRepository,</span> you'll get + an instance of the<span class="style1"> Repository</span> class. In this + case, <span class="style1">IRepository</span> is the PluginType (what you're + asking for) and <span class="style1">Repository</span> is the "PluggedType" (the + concrete class you'll get).</p> +<p>Another example of the PluginType / PluggedType nomenclature is in the Xml + configuration on the <DefaultInstance> node. The example below configures + the default ISessionSource:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red255\green0\blue0;\red0\green0\blue0;}??\fs20 \cf1 <\cf3 DefaultInstance\par ??\cf1 \cf4 PluginType\cf1 =\cf0 "\cf1 ShadeTree.DomainModel.ISessionSource,ShadeTree.DomainModel\cf0 "\par ??\cf1 \cf4 PluggedType\cf1 =\cf0 "\cf1 ShadeTree.DomainModel.SessionSource,ShadeTree.DomainModel\cf0 "\cf1 >\par ?? <\cf3 properties\cf1 >\par ?? <\cf3 Pair\cf1 \cf4 Key\cf1 =\cf0 "\cf1 connection.provider\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 NHibernate.Connection.DriverConnectionProvider\cf0 "\cf1 />\par ?? <\cf3 Pair\cf1 \cf4 Key\cf1 =\cf0 "\cf1 connection.driver_class\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 NHibernate.Driver.SqlClientDriver\cf0 "\cf1 />\par ?? <\cf3 Pair\cf1 \cf4 Key\cf1 =\cf0 "\cf1 dialect\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 NHibernate.Dialect.MsSql2000Dialect\cf0 "\cf1 />\par ?? <\cf3 Pair\cf1 \cf4 Key\cf1 =\cf0 "\cf1 hibernate.dialect\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 NHibernate.Dialect.MsSql2000Dialect\cf0 "\cf1 />\par ?? <\cf3 Pair\cf1 \cf4 Key\cf1 =\cf0 "\cf1 use_outer_join\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 true\cf0 "\cf1 />\par ?? <\cf3 Pair\cf1 \cf4 Key\cf1 =\cf0 "\cf1 connection.connection_string\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 Data Source=localhost;Initial Catalog=Blue;Trusted_Connection=yes;\cf0 "\cf1 />\par ?? <\cf3 Pair\cf1 \cf4 Key\cf1 =\cf0 "\cf1 show_sql\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 true\cf0 "\cf1 />\par ?? </\cf3 properties\cf1 >\par ?? </\cf3 DefaultInstance\cf1 >} +--> +<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;"> <</span><span style="color: #a31515;">DefaultInstance</span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> </span><span style="color: red;"> + PluginType</span><span style="color: blue;">=</span>"<span style="color: blue;">ShadeTree.DomainModel.ISessionSource,ShadeTree.DomainModel</span>"</p> + <p style="margin: 0px;"> + <span style="color: blue;"> </span><span style="color: red;"> + PluggedType</span><span style="color: blue;">=</span>"<span + style="color: blue;">ShadeTree.DomainModel.SessionSource,ShadeTree.DomainModel</span>"<span + style="color: blue;">></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">properties</span><span style="color: blue;">></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">Pair</span><span style="color: blue;"> </span> + <span style="color: red;">Key</span><span style="color: blue;">=</span>"<span + style="color: blue;">connection.provider</span>"<span style="color: blue;"> + </span><span style="color: red;">Value</span><span style="color: blue;">=</span>"<span + style="color: blue;">NHibernate.Connection.DriverConnectionProvider</span>"<span + style="color: blue;"> /></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">Pair</span><span style="color: blue;"> </span> + <span style="color: red;">Key</span><span style="color: blue;">=</span>"<span + style="color: blue;">connection.driver_class</span>"<span + style="color: blue;"> </span><span style="color: red;">Value</span><span + style="color: blue;">=</span>"<span style="color: blue;">NHibernate.Driver.SqlClientDriver</span>"<span + style="color: blue;"> /></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">Pair</span><span style="color: blue;"> </span> + <span style="color: red;">Key</span><span style="color: blue;">=</span>"<span + style="color: blue;">dialect</span>"<span style="color: blue;"> </span> + <span style="color: red;">Value</span><span style="color: blue;">=</span>"<span + style="color: blue;">NHibernate.Dialect.MsSql2000Dialect</span>"<span + style="color: blue;"> /></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">Pair</span><span style="color: blue;"> </span> + <span style="color: red;">Key</span><span style="color: blue;">=</span>"<span + style="color: blue;">hibernate.dialect</span>"<span style="color: blue;"> + </span><span style="color: red;">Value</span><span style="color: blue;">=</span>"<span + style="color: blue;">NHibernate.Dialect.MsSql2000Dialect</span>"<span + style="color: blue;"> /></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">Pair</span><span style="color: blue;"> </span> + <span style="color: red;">Key</span><span style="color: blue;">=</span>"<span + style="color: blue;">use_outer_join</span>"<span style="color: blue;"> + </span><span style="color: red;">Value</span><span style="color: blue;">=</span>"<span + style="color: blue;">true</span>"<span style="color: blue;"> /></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">Pair</span><span style="color: blue;"> </span> + <span style="color: red;">Key</span><span style="color: blue;">=</span>"<span + style="color: blue;">connection.connection_string</span>"<span + style="color: blue;"> </span><span style="color: red;">Value</span><span + style="color: blue;">=</span>"a connection string"<span + style="color: blue;"> /></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">Pair</span><span style="color: blue;"> </span> + <span style="color: red;">Key</span><span style="color: blue;">=</span>"<span + style="color: blue;">show_sql</span>"<span style="color: blue;"> </span> + <span style="color: red;">Value</span><span style="color: blue;">=</span>"<span + style="color: blue;">true</span>"<span style="color: blue;"> /></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> </</span><span + style="color: #a31515;">properties</span><span style="color: blue;">></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> </</span><span style="color: #a31515;">DefaultInstance</span><span + style="color: blue;">></span></p> +</div> +<!--EndFragment--> +<p> </p> + <h4>Instance</h4> + <p>In StructureMap terms, an "Instance" is a named way to build or locate an object + instance for a requested PluginType. There is an actual class in + StructureMap 2.5 that represents an "Instance." An abreviated version of + the abstract Instance class 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;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 abstract\cf0 \cf3 class\cf0 \cf4 Instance\cf0 : \cf4 IDiagnosticInstance\par ??\cf0 \{\par ?? \cf3 private\cf0 \cf3 readonly\cf0 \cf3 string\cf0 _originalName;\par ?? \cf3 private\cf0 \cf4 InstanceInterceptor\cf0 _interceptor = \cf3 new\cf0 \cf4 NulloInterceptor\cf0 ();\par ?? \cf3 private\cf0 \cf3 string\cf0 _name = \cf4 Guid\cf0 .NewGuid().ToString();\par ??\par ??\par ?? \cf3 protected\cf0 Instance()\par ?? \{\par ?? _originalName = _name;\par ?? \}\par ??\par ?? \cf3 public\cf0 \cf3 string\cf0 Name\par ?? \{\par ?? \cf3 get\cf0 \{ \cf3 return\cf0 _name; \}\par ?? \cf3 set\cf0 \{ _name = \cf3 value\cf0 ; \}\par ?? \}\par ??\par ?? \cf3 public\cf0 \cf3 virtual\cf0 \cf3 object\cf0 Build(\cf4 Type\cf0 pluginType, \cf4 IBuildSession\cf0 session)\par ?? \{\par ?? \cf3 object\cf0 rawValue = createRawObject(pluginType, session);\par ?? \cf3 return\cf0 applyInterception(rawValue, pluginType);\par ?? \}\par ??\par ?? \cf3 private\cf0 \cf3 object\cf0 createRawObject(\cf4 Type\cf0 pluginType, \cf4 IBuildSession\cf0 session)\par ?? \{\par ?? \cf3 try\par ??\cf0 \{\par ?? \cf3 return\cf0 build(pluginType, session);\par ?? \}\par ?? \cf3 catch\cf0 (\cf4 StructureMapException\cf0 ex)\par ?? \{\par ?? \cf3 throw\cf0 ;\par ?? \}\par ?? \cf3 catch\cf0 (\cf4 Exception\cf0 ex)\par ?? \{\par ?? \cf3 throw\cf0 \cf3 new\cf0 \cf4 StructureMapException\cf0 (400, ex);\par ?? \}\par ?? \}\par ??\par ?? \cf3 protected\cf0 \cf3 abstract\cf0 \cf3 object\cf0 build(\cf4 Type\cf0 pluginType, \cf4 IBuildSession\cf0 session);\par ??\par ?? \cf3 public\cf0 \cf4 InstanceInterceptor\cf0 Interceptor\par ?? \{\par ?? \cf3 get\cf0 \{ \cf3 return\cf0 _interceptor; \}\par ?? \cf3 set\cf0 \{ _interceptor = \cf3 value\cf0 ; \}\par ?? \}\par ??\par ??\par ??\par ??\cf3 #region\cf0 IDiagnosticInstance Members\par ??\par ?? \cf3 bool\cf0 \cf4 IDiagnosticInstance\cf0 .CanBePartOfPluginFamily(\cf4 PluginFamily\cf0 family)\par ?? \{\par ?? \cf3 return\cf0 canBePartOfPluginFamily(family);\par ?? \}\par ??\par ?? \cf4 Instance\cf0 \cf4 IDiagnosticInstance\cf0 .FindInstanceForProfile(\cf4 PluginFamily\cf0 family, \cf3 string\cf0 profileName, \cf4 GraphLog\cf0 log)\par ?? \{\par ?? \cf3 return\cf0 findMasterInstance(family, profileName, log);\par ?? \}\par ??\par ?? \cf4 InstanceToken\cf0 \cf4 IDiagnosticInstance\cf0 .CreateToken()\par ?? \{\par ?? \cf3 return\cf0 \cf3 new\cf0 \cf4 InstanceToken\cf0 (Name, getDescription());\par ?? \}\par ??\par ?? \cf3 void\cf0 \cf4 IDiagnosticInstance\cf0 .Preprocess(\cf4 PluginFamily\cf0 family)\par ?? \{\par ?? preprocess(family);\par ?? \}\par ??\par ?? \cf3 protected\cf0 \cf3 virtual\cf0 \cf3 void\cf0 preprocess(\cf4 PluginFamily\cf0 family)\par ?? \{\par ?? \cf5 // no-op;\par ??\cf0 \}\par ??\par ?? \cf3 protected\cf0 \cf3 abstract\cf0 \cf3 string\cf0 getDescription();\par ??\par ??\cf3 #endregion\par ??\par ??\cf0 \cf3 protected\cf0 \cf3 void\cf0 replaceNameIfNotAlreadySet(\cf3 string\cf0 name)\par ?? \{\par ?? \cf3 if\cf0 (_name == _originalName)\par ?? \{\par ?? _name = name;\par ?? \}\par ?? \}\par ??\par ??\par ??\par ?? \cf3 private\cf0 \cf3 object\cf0 applyInterception(\cf3 object\cf0 rawValue, \cf4 Type\cf0 pluginType)\par ?? \{\par ?? \cf3 try\par ??\cf0 \{\par ?? \cf5 // Intercept with the Instance-specific InstanceInterceptor\par ??\cf0 \cf3 return\cf0 _interceptor.Process(rawValue);\par ?? \}\par ?? \cf3 catch\cf0 (\cf4 Exception\cf0 e)\par ?? \{\par ?? \cf3 throw\cf0 \cf3 new\cf0 \cf4 StructureMapException\cf0 (270, e, Name, pluginType);\par ?? \}\par ?? \}\par ??\par ?? \cf3 protected\cf0 \cf3 abstract\cf0 \cf3 object\cf0 build(\cf4 Type\cf0 pluginType, \cf4 IBuildSession\cf0 session);\par ??\par ?? \cf3 protected\cf0 \cf3 virtual\cf0 \cf4 Plugin\cf0 findPlugin(\cf4 PluginCollection\cf0 plugins)\par ?? \{\par ?? \cf3 return\cf0 \cf3 null\cf0 ;\par ?? \}\par ??\par ?? \cf3 protected\cf0 \cf3 virtual\cf0 \cf4 Instance\cf0 findMasterInstance(\cf4 PluginFamily\cf0 family, \cf3 string\cf0 profileName, \cf4 GraphLog\cf0 log)\par ?? \{\par ?? \cf3 return\cf0 \cf3 this\cf0 ;\par ?? \}\par ??\par ?? \cf3 protected\cf0 \cf3 virtual\cf0 \cf3 bool\cf0 canBePartOfPluginFamily(\cf4 PluginFamily\cf0 family)\par ?? \{\par ?? \cf3 return\cf0 \cf3 true\cf0 ;\par ?? \}\par ??\par ??\par ??\par ?? \cf3 internal\cf0 \cf3 virtual\cf0 \cf3 bool\cf0 Matches(\cf4 Plugin\cf0 plugin)\par ?? \{\par ?? \cf3 return\cf0 \cf3 false\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;"> + abstract</span> <span style="color: blue;">class</span> + <span style="color: #2b91af;">Instance</span> : <span style="color: #2b91af;"> + IDiagnosticInstance</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: blue;">string</span> Name</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: blue;">get</span> { <span style="color: blue;">return</span> + _name; }</p> + <p style="margin: 0px;"> + + <span style="color: blue;">set</span> { _name = <span style="color: blue;">value</span>; + }</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: blue;">virtual</span> <span style="color: blue;">object</span> + Build(<span style="color: #2b91af;">Type</span> pluginType, + <span style="color: #2b91af;">IBuildSession</span> session)</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: blue;">object</span> rawValue = createRawObject(pluginType, + session);</p> + <p style="margin: 0px;"> + + <span style="color: blue;">return</span> applyInterception(rawValue, + pluginType);</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: blue;">private</span> + <span style="color: blue;">object</span> createRawObject(<span + style="color: #2b91af;">Type</span> pluginType, + <span style="color: #2b91af;">IBuildSession</span> session)</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: blue;">try</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: blue;">return</span> build(pluginType, session);</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + + <span style="color: blue;">catch</span> (<span style="color: #2b91af;">StructureMapException</span> + ex)</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: blue;">throw</span>;</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + + <span style="color: blue;">catch</span> (<span style="color: #2b91af;">Exception</span> + ex)</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: blue;">throw</span> <span style="color: blue;">new</span> + <span style="color: #2b91af;">StructureMapException</span>(400, ex);</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: blue;">protected</span> + <span style="color: blue;">abstract</span> <span style="color: blue;">object</span> + build(<span style="color: #2b91af;">Type</span> pluginType, + <span style="color: #2b91af;">IBuildSession</span> session);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + }</p> + </div> +<!--EndFragment--> +<p>A single Instance can be assigned to a PluginType as the default. When you + call ObjectFactory.GetInstance<T>(), StructureMap looks for the default Instance + object for PluginType T, then executes the Instance.Build(Type, IBuildSession) + method to create a new object or get an existing object. Note the abstract + build(Type, IBuildSession) method. This is a Template Method that can be + overriden to write your own customized Instance type.</p> +<p>When you call ObjectFactory.Get</p> + <h4>Scoping</h4> + <p>a;lskdfje</p> + <h4>PluginFamily</h4> + <p>a;lskdfj</p> + <h4>Profile</h4> + <p>a;lskdfj</p> + <h4>Interceptor</h4> + <p>a;lskdfj</p> + <h4>PostProcessor</h4> + <p>a;lskdfj</p> + </body> +</html> \ No newline at end of file Added: trunk/Source/StructureMap/ConfigurationClasses.cd =================================================================== --- trunk/Source/StructureMap/ConfigurationClasses.cd (rev 0) +++ trunk/Source/StructureMap/ConfigurationClasses.cd 2008-08-07 20:23:07 UTC (rev 129) @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8"?> +<ClassDiagram MajorVersion="1" MinorVersion="1"> + <Class Name="StructureMap.Container" Collapsed="true" BaseTypeListCollapsed="true"> + <Position X="3.25" Y="0.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAgAAAAAgAAgIBCAAAABAAgCQAAACBAICAAAQA=</HashCode> + <FileName>Container.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" Collapsed="true" /> + </Class> + <Class Name="StructureMap.InstanceBuilder" Collapsed="true"> + <Position X="5" Y="0.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAQAAAAAAAAQAAAAAAAACAAAAAAAAAAAA=</HashCode> + <FileName>InstanceBuilder.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="StructureMap.InstanceFactory" Collapsed="true" BaseTypeListCollapsed="true"> + <Position X="5" Y="1.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AACBEAAAEgAAAAAAgQAACAEAAAAAgQkAAAAAACAAAAA=</HashCode> + <FileName>InstanceFactory.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" Collapsed="true" /> + </Class> + <Class Name="StructureMap.InstanceCache" Collapsed="true"> + <Position X="3.25" Y="1.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAQAABABAAAAAAAAAAAAAAAAgAAAAAAAAAAA=</HashCode> + <FileName>InstanceCache.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="StructureMap.InstanceBuilderList" Collapsed="true"> + <Position X="6.75" Y="0.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAIAAAAAAAAAAgAQARAAAAAAgIAAEAAAAAAAAAAAiAA=</HashCode> + <FileName>InstanceBuilderList.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="StructureMap.PipelineGraph" Collapsed="true"> + <Position X="6.75" Y="1.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AIABgABAAgIABkQAAAIKAAAAAAghAAEgAAAAACAgAAA=</HashCode> + <FileName>PipelineGraph.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="StructureMap.Pipeline.BuildPolicy" Collapsed="true"> + <Position X="9" Y="2" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAABA=</HashCode> + <FileName>Pipeline\BuildPolicy.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Interface Name="StructureMap.IPipelineGraphVisitor" Collapsed="true"> + <Position X="3.25" Y="2.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAQAAAAAAAAAA=</HashCode> + <FileName>PipelineGraph.cs</FileName> + </TypeIdentifier> + </Interface> + <Delegate Name="StructureMap.MissingFactoryFunction" Collapsed="true"> + <Position X="3.25" Y="3.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAACAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode> + <FileName>PipelineGraph.cs</FileName> + </TypeIdentifier> + </Delegate> + <Font Name="Segoe UI" Size="9" /> +</ClassDiagram> \ No newline at end of file Modified: trunk/Source/StructureMap/Emitting/ArgumentEmitter.cs =================================================================== --- trunk/Source/StructureMap/Emitting/ArgumentEmitter.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/ArgumentEmitter.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -20,41 +20,43 @@ this.ilgen = ilgen; } + private void addSetter(ParameterEmitter emitter, PropertyInfo property, bool isMandatory ) + { + if (isMandatory) + { + emitter.MandatorySetter(ilgen, property); + } + else + { + emitter.OptionalSetter(ilgen, property); + } + } + #region IArgumentVisitor Members public void PrimitiveSetter(PropertyInfo property, bool isMandatory) { - if (!isMandatory) return; - - _primitive.Setter(ilgen, property); + addSetter(_primitive, property, isMandatory); } public void StringSetter(PropertyInfo property, bool isMandatory) { - if (!isMandatory) return; - - _string.Setter(ilgen, property); + addSetter(_string, property, isMandatory); } public void EnumSetter(PropertyInfo property, bool isMandatory) { - if (!isMandatory) return; - - _enum.Setter(ilgen, property); + addSetter(_enum, property, isMandatory); } public void ChildSetter(PropertyInfo property, bool isMandatory) { - if (!isMandatory) return; - - _child.Setter(ilgen, property); + addSetter(_child, property, isMandatory); } public void ChildArraySetter(PropertyInfo property, bool isMandatory) { - if (!isMandatory) return; - - _childArray.Setter(ilgen, property); + addSetter(_childArray, property, isMandatory); } public void PrimitiveParameter(ParameterInfo parameter) Modified: trunk/Source/StructureMap/Emitting/BuildInstanceMethod.cs =================================================================== --- trunk/Source/StructureMap/Emitting/BuildInstanceMethod.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/BuildInstanceMethod.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -38,7 +38,15 @@ protected override void Generate(ILGenerator ilgen) { - ilgen.DeclareLocal(typeof (object)); + ilgen.Emit(OpCodes.Nop); + ilgen.DeclareLocal(_plugin.PluggedType); + ilgen.DeclareLocal(typeof(object)); + + for (int i = 0; i < _plugin.Setters.OptionalCount; i++) + { + ilgen.DeclareLocal(typeof (bool)); + } + ArgumentEmitter arguments = new ArgumentEmitter(ilgen); _plugin.VisitConstructor(arguments); @@ -49,9 +57,12 @@ _plugin.VisitSetters(arguments); + ilgen.Emit(OpCodes.Ldloc_0); + ilgen.Emit(OpCodes.Stloc_1); + ilgen.Emit(OpCodes.Br_S, label); ilgen.MarkLabel(label); - ilgen.Emit(OpCodes.Ldloc_0); + ilgen.Emit(OpCodes.Ldloc_1); ilgen.Emit(OpCodes.Ret); } } Modified: trunk/Source/StructureMap/Emitting/ClassBuilder.cs =================================================================== --- trunk/Source/StructureMap/Emitting/ClassBuilder.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/ClassBuilder.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -2,6 +2,7 @@ using System.Collections; using System.Reflection; using System.Reflection.Emit; +using StructureMap.Emitting.Parameters; namespace StructureMap.Emitting { @@ -102,8 +103,7 @@ gen.Emit(OpCodes.Nop); gen.Emit(OpCodes.Ldtoken, pluggedType); - MethodInfo method = typeof (Type).GetMethod("GetTypeFromHandle"); - gen.Emit(OpCodes.Call, method); + gen.Emit(OpCodes.Call, Methods.GET_TYPE_FROM_HANDLE); gen.Emit(OpCodes.Stloc_0); Modified: trunk/Source/StructureMap/Emitting/DynamicAssembly.cs =================================================================== --- trunk/Source/StructureMap/Emitting/DynamicAssembly.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/DynamicAssembly.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -13,14 +13,14 @@ { private Hashtable _Classes; private bool _isCompiled = false; - private string _Name; - private AssemblyBuilder assemBuilder; + private string _name; + private AssemblyBuilder _assemblyBuilder; private string DLLName; - private ModuleBuilder module; + private ModuleBuilder _module; - public DynamicAssembly(string Name) + public DynamicAssembly(string name) { - _Name = Name; + _name = name; _Classes = new Hashtable(); Init(); @@ -29,7 +29,7 @@ public string Name { - get { return _Name; } + get { return _name; } } public bool IsCompiled @@ -46,25 +46,27 @@ assemName.CultureInfo = new CultureInfo("en"); assemName.SetPublicKeyToken(null); - DLLName = _Name + ".DLL"; - //assemBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemName, AssemblyBuilderAccess.RunAndSave); - assemBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemName, AssemblyBuilderAccess.Run); + DLLName = Name + ".dll"; + _assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemName, AssemblyBuilderAccess.RunAndSave); + //_assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemName, AssemblyBuilderAccess.Run); - //module = assemBuilder.DefineDynamicModule(this.Name, DLLName); - module = assemBuilder.DefineDynamicModule(Name); + _module = _assemblyBuilder.DefineDynamicModule(this.Name, DLLName); + + + //_module = _assemblyBuilder.DefineDynamicModule(Name); } public ClassBuilder AddClass(string ClassName) { - ClassBuilder newClass = new ClassBuilder(module, ClassName); + ClassBuilder newClass = new ClassBuilder(_module, ClassName); storeClass(newClass); return newClass; } public ClassBuilder AddClass(string ClassName, Type superType) { - ClassBuilder newClass = new ClassBuilder(module, ClassName, superType); + ClassBuilder newClass = new ClassBuilder(_module, ClassName, superType); storeClass(newClass); return newClass; } @@ -82,10 +84,12 @@ newClass.Bake(); } + _assemblyBuilder.Save(_name + ".dll"); + //assemBuilder.Save(DLLName); //Assembly assem = AppDomain.CurrentDomain.Load(this.Name); _isCompiled = true; - return (Assembly) assemBuilder; + return (Assembly) _assemblyBuilder; //return assem; } } Modified: trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs =================================================================== --- trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -16,8 +16,9 @@ public InstanceBuilderAssembly(Type pluginType, IEnumerable<Plugin> plugins) { - string assemblyName = guidString() + "InstanceBuilderAssembly"; + string assemblyName = "Builders" + guidString(); _dynamicAssembly = new DynamicAssembly(assemblyName); + _pluginType = pluginType; foreach (Plugin plugin in plugins) @@ -28,7 +29,7 @@ private static string guidString() { - return Guid.NewGuid().ToString().Replace(".", ""); + return Guid.NewGuid().ToString().Replace(".", "").Replace("-", ""); } /// <summary> @@ -85,6 +86,7 @@ public List<InstanceBuilder> Compile() { Assembly assembly = _dynamicAssembly.Compile(); + return _classNames.ConvertAll<InstanceBuilder>( Modified: trunk/Source/StructureMap/Emitting/Parameters/ChildArrayParameterEmitter.cs =================================================================== --- trunk/Source/StructureMap/Emitting/Parameters/ChildArrayParameterEmitter.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/Parameters/ChildArrayParameterEmitter.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -24,22 +24,18 @@ { ilgen.Emit(OpCodes.Ldarg_2); - //ilgen.Emit(OpCodes.Ldstr, argumentType.GetElementType().AssemblyQualifiedName); ilgen.Emit(OpCodes.Ldtoken, argumentType.GetElementType()); - MethodInfo method = typeof (Type).GetMethod("GetTypeFromHandle"); - ilgen.Emit(OpCodes.Call, method); + ilgen.Emit(OpCodes.Call, Methods.GET_TYPE_FROM_HANDLE); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldstr, argumentName); - callInstanceMemento(ilgen, "GetChildrenArray"); - - MethodInfo methodCreateInstanceArray = (typeof (IBuildSession).GetMethod("CreateInstanceArray")); - ilgen.Emit(OpCodes.Callvirt, methodCreateInstanceArray); + ilgen.Emit(OpCodes.Callvirt, Methods.GET_CHILDREN_ARRAY); + ilgen.Emit(OpCodes.Callvirt, Methods.CREATE_INSTANCE_ARRAY); cast(ilgen, argumentType); } - public void Setter(ILGenerator ilgen, PropertyInfo property) + public override void MandatorySetter(ILGenerator ilgen, PropertyInfo property) { ilgen.Emit(OpCodes.Ldloc_0); putChildArrayFromInstanceMementoOntoStack(ilgen, property.PropertyType, property.Name); Modified: trunk/Source/StructureMap/Emitting/Parameters/ChildParameterEmitter.cs =================================================================== --- trunk/Source/StructureMap/Emitting/Parameters/ChildParameterEmitter.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/Parameters/ChildParameterEmitter.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -25,16 +25,15 @@ ilgen.Emit(OpCodes.Ldtoken, parameterType); - MethodInfo method = typeof (Type).GetMethod("GetTypeFromHandle"); - ilgen.Emit(OpCodes.Call, method); + ilgen.Emit(OpCodes.Call, Methods.GET_TYPE_FROM_HANDLE); ilgen.Emit(OpCodes.Ldarg_2); + ilgen.Emit(OpCodes.Callvirt, Methods.GET_CHILD); - callInstanceMemento(ilgen, "GetChild"); cast(ilgen, parameterType); } - public void Setter(ILGenerator ilgen, PropertyInfo property) + public override void MandatorySetter(ILGenerator ilgen, PropertyInfo property) { ilgen.Emit(OpCodes.Ldloc_0); Modified: trunk/Source/StructureMap/Emitting/Parameters/EnumParameterEmitter.cs =================================================================== --- trunk/Source/StructureMap/Emitting/Parameters/EnumParameterEmitter.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/Parameters/EnumParameterEmitter.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -19,27 +19,20 @@ private void putEnumerationValueFromMementoOntoStack(ILGenerator ilgen, Type argumentType, string argumentName) { - Type typeItself = typeof (Type); - MethodInfo getTypeFromHandleMethod = typeItself.GetMethod("GetTypeFromHandle"); - ilgen.Emit(OpCodes.Ldtoken, argumentType); - ilgen.Emit(OpCodes.Call, getTypeFromHandleMethod); + ilgen.Emit(OpCodes.Call, Methods.GET_TYPE_FROM_HANDLE); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldstr, argumentName); - callInstanceMemento(ilgen, "GetProperty"); + ilgen.Emit(OpCodes.Callvirt, Methods.GET_PROPERTY); ilgen.Emit(OpCodes.Ldc_I4_1); + ilgen.Emit(OpCodes.Call, Methods.ENUM_PARSE); - Type enumType = typeof (Enum); - MethodInfo parseMethod = - enumType.GetMethod("Parse", new Type[] {typeItself, typeof (string), typeof (bool)}); - ilgen.Emit(OpCodes.Call, parseMethod); - ilgen.Emit(OpCodes.Unbox, argumentType); ilgen.Emit(OpCodes.Ldind_I4); } - public void Setter(ILGenerator ilgen, PropertyInfo property) + public override void MandatorySetter(ILGenerator ilgen, PropertyInfo property) { ilgen.Emit(OpCodes.Ldloc_0); putEnumerationValueFromMementoOntoStack(ilgen, property.PropertyType, property.Name); Added: trunk/Source/StructureMap/Emitting/Parameters/Methods.cs =================================================================== --- trunk/Source/StructureMap/Emitting/Parameters/Methods.cs (rev 0) +++ trunk/Source/StructureMap/Emitting/Parameters/Methods.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using StructureMap.Pipeline; +using StructureMap.Util; + +namespace StructureMap.Emitting.Parameters +{ + public static class Methods + { + public static MethodInfo HAS_PROPERTY = ReflectionHelper.GetMethod<IConfiguredInstance>(i => i.HasProperty(null)); + public static MethodInfo GET_CHILDREN_ARRAY = ReflectionHelper.GetMethod<IConfiguredInstance>(i => i.GetChildrenArray(null)); + public static MethodInfo GET_CHILD = ReflectionHelper.GetMethod<IConfiguredInstance>(i => i.GetChild(null, null, null)); + public static MethodInfo CREATE_INSTANCE_ARRAY = ReflectionHelper.GetMethod<IBuildSession>(i => i.CreateInstanceArray(null, null)); + + public static MethodInfo GET_TYPE_FROM_HANDLE = typeof(Type).GetMethod("GetTypeFromHandle"); + + public static readonly MethodInfo GET_PROPERTY = + ReflectionHelper.GetMethod<IConfiguredInstance>(i => i.GetProperty(null)); + + private static Cache<Type, MethodInfo> _parseMethods = new Cache<Type, MethodInfo>(findParse); + + private static MethodInfo findParse(Type t) + { + return t.GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, null, new[] {typeof (string)}, null); + } + + public static MethodInfo ENUM_PARSE = typeof (Enum).GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, null, new[]{typeof(Type), typeof(string), typeof(bool)}, null); + + public static MethodInfo ParseFor(Type type) + { + return _parseMethods.Retrieve(type); + } + } +} Modified: trunk/Source/StructureMap/Emitting/Parameters/ParameterEmitter.cs =================================================================== --- trunk/Source/StructureMap/Emitting/Parameters/ParameterEmitter.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/Parameters/ParameterEmitter.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -12,12 +12,6 @@ /// </summary> public abstract class ParameterEmitter { - protected void callInstanceMemento(ILGenerator ilgen, string methodName) - { - MethodInfo _method = typeof (IConfiguredInstance).GetMethod(methodName); - ilgen.Emit(OpCodes.Callvirt, _method); - } - protected void cast(ILGenerator ilgen, Type parameterType) { //NOTE: According to the docs, Unbox_Any, when called on a ref type, will just do a Castclass @@ -34,5 +28,28 @@ } } + + public abstract void MandatorySetter(ILGenerator ilgen, PropertyInfo property); + + public void OptionalSetter(ILGenerator ilgen, PropertyInfo property) + { + ilgen.Emit(OpCodes.Ldarg_1); + ilgen.Emit(OpCodes.Ldstr, property.Name); + ilgen.Emit(OpCodes.Callvirt, Methods.HAS_PROPERTY); + ilgen.Emit(OpCodes.Ldc_I4_0); + ilgen.Emit(OpCodes.Ceq); + ilgen.Emit(OpCodes.Stloc_2); + ilgen.Emit(OpCodes.Ldloc_2); + + Label label = ilgen.DefineLabel(); + + ilgen.Emit(OpCodes.Brtrue_S, label); + + MandatorySetter(ilgen, property); + + ilgen.Emit(OpCodes.Nop); + + ilgen.MarkLabel(label); + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Emitting/Parameters/PrimitiveParameterEmitter.cs =================================================================== --- trunk/Source/StructureMap/Emitting/Parameters/PrimitiveParameterEmitter.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/Parameters/PrimitiveParameterEmitter.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -13,30 +13,27 @@ { ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldstr, parameter.Name); - callInstanceMemento(ilgen, "GetProperty"); + ilgen.Emit(OpCodes.Callvirt, Methods.GET_PROPERTY); callParse(parameter.ParameterType, ilgen); } private void callParse(Type argumentType, ILGenerator ilgen) { - BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public; - MethodInfo parseMethod = - argumentType.GetMethod("Parse", bindingAttr, null, new [] {typeof (string)}, null); - ilgen.Emit(OpCodes.Call, parseMethod); + ilgen.Emit(OpCodes.Call, Methods.ParseFor(argumentType)); } - - public void Setter(ILGenerator ilgen, PropertyInfo property) + public override void MandatorySetter(ILGenerator ilgen, PropertyInfo property) { ilgen.Emit(OpCodes.Ldloc_0); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldstr, property.Name); - callInstanceMemento(ilgen, "GetProperty"); + ilgen.Emit(OpCodes.Callvirt, Methods.GET_PROPERTY); callParse(property.PropertyType, ilgen); MethodInfo method = property.GetSetMethod(); ilgen.Emit(OpCodes.Callvirt, method); } + } } \ No newline at end of file Modified: trunk/Source/StructureMap/Emitting/Parameters/StringParameterEmitter.cs =================================================================== --- trunk/Source/StructureMap/Emitting/Parameters/StringParameterEmitter.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Emitting/Parameters/StringParameterEmitter.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -1,5 +1,6 @@ using System.Reflection; using System.Reflection.Emit; +using StructureMap.Pipeline; namespace StructureMap.Emitting.Parameters { @@ -12,19 +13,16 @@ { ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldstr, parameter.Name); - callInstanceMemento(ilgen, "GetProperty"); + ilgen.Emit(OpCodes.Callvirt, Methods.GET_PROPERTY); } - - public void Setter(ILGenerator ilgen, PropertyInfo property) + public override void MandatorySetter(ILGenerator ilgen, PropertyInfo property) { ilgen.Emit(OpCodes.Ldloc_0); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldstr, property.Name); - callInstanceMemento(ilgen, "GetProperty"); - - MethodInfo method = property.GetSetMethod(); - ilgen.Emit(OpCodes.Callvirt, method); + ilgen.Emit(OpCodes.Callvirt, Methods.GET_PROPERTY); + ilgen.Emit(OpCodes.Callvirt, property.GetSetMethod()); } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Graph/ITypeScanner.cs =================================================================== --- trunk/Source/StructureMap/Graph/ITypeScanner.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Graph/ITypeScanner.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -17,8 +17,10 @@ { if (!IsConcrete(type)) return; + + Type pluginType = FindPluginType(type); - if (pluginType != null) + if (pluginType != null && Plugin.CreateForConcreteType(type) != null) { registry.ForRequestedType(pluginType).AddInstance(new ConfiguredInstance(type)); } Modified: trunk/Source/StructureMap/Graph/Plugin.cs =================================================================== --- trunk/Source/StructureMap/Graph/Plugin.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Graph/Plugin.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -84,7 +84,7 @@ return new ConfiguredInstance(PluggedType).WithConcreteKey(ConcreteKey).WithName(ConcreteKey); } - public string FindFirstConstructorArgumentOfType<T>() + public string FindArgumentNameForType<T>() { string returnValue = _constructor.FindFirstConstructorArgumentOfType<T>() ?? @@ -135,5 +135,10 @@ return new Plugin(type, DEFAULT); } + + public bool HasOptionalSetters() + { + return _setters.OptionalCount > 0; + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Building.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Building.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Building.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -66,5 +66,9 @@ } } + bool IConfiguredInstance.HasProperty(string propertyName) + { + return _properties.ContainsKey(propertyName) || _children.ContainsKey(propertyName) || _arrays.ContainsKey(propertyName); + } } } Modified: trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Expressions.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Expressions.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Expressions.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -110,7 +110,7 @@ private string findPropertyName<T>() { Plugin plugin = new Plugin(_pluggedType); - string propertyName = plugin.FindFirstConstructorArgumentOfType<T>(); + string propertyName = plugin.FindArgumentNameForType<T>(); if (string.IsNullOrEmpty(propertyName)) { @@ -233,6 +233,12 @@ LiteralInstance instance = new LiteralInstance(value); return Is(instance); } + + public ConfiguredInstance IsAutoFilled() + { + DefaultInstance instance = new DefaultInstance(); + return Is(instance); + } } #endregion Modified: trunk/Source/StructureMap/Pipeline/ConfiguredInstance.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/ConfiguredInstance.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Pipeline/ConfiguredInstance.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -151,6 +151,8 @@ private void setChild(string name, Instance instance) { + if (instance == null) return; + _children.Add(name, instance); } @@ -188,12 +190,5 @@ } } - public void ForProperty(string propertyName, Action<string> action) - { - if (_properties.ContainsKey(propertyName)) - { - action(_properties[propertyName]); - } - } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Pipeline/DefaultInstance.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/DefaultInstance.cs 2008-07-27 14:01:47 UTC (rev 128) +++ trunk/Source/StructureMap/Pipeline/DefaultInstance.cs 2008-08-07 20:23:07 UTC (rev 129) @@ -4,6 +4,11 @@ { public class DefaultInstance : Instance { + public DefaultInstance() + { + int x = 1; + } ... [truncated message content] |