From: <jer...@us...> - 2008-08-13 21:51:32
|
Revision: 138 http://structuremap.svn.sourceforge.net/structuremap/?rev=138&view=rev Author: jeremydmiller Date: 2008-08-13 21:51:26 +0000 (Wed, 13 Aug 2008) Log Message: ----------- changes for setter injection problems Modified Paths: -------------- trunk/Source/StructureMap/Configuration/DSL/Registry.cs trunk/Source/StructureMap/Container.cs trunk/Source/StructureMap/Emitting/Parameters/ChildParameterEmitter.cs trunk/Source/StructureMap/Graph/Plugin.cs trunk/Source/StructureMap/Graph/PluginGraph.cs trunk/Source/StructureMap/Graph/SetterPropertyCollection.cs trunk/Source/StructureMap/ObjectFactory.cs trunk/Source/StructureMap.Testing/Graph/PluginTester.cs trunk/Source/StructureMap.Testing/Pipeline/OptionalSetterInjectionTester.cs Added Paths: ----------- trunk/Source/StructureMap/Graph/PluginCache.cs Modified: trunk/Source/StructureMap/Configuration/DSL/Registry.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -242,5 +242,11 @@ { return 0; } + + public CreatePluginFamilyExpression<PLUGINTYPE> FillAllPropertiesOfType<PLUGINTYPE>() + { + PluginCache.AddFilledType(typeof(PLUGINTYPE)); + return ForRequestedType<PLUGINTYPE>(); + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Container.cs =================================================================== --- trunk/Source/StructureMap/Container.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap/Container.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -59,6 +59,8 @@ pluginGraph.Log.AssertFailures(); _pipelineGraph = new PipelineGraph(pluginGraph); + + PluginCache.Compile(); } protected MissingFactoryFunction onMissingFactory Modified: trunk/Source/StructureMap/Emitting/Parameters/ChildParameterEmitter.cs =================================================================== --- trunk/Source/StructureMap/Emitting/Parameters/ChildParameterEmitter.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap/Emitting/Parameters/ChildParameterEmitter.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -40,6 +40,14 @@ putChildObjectOnStack(ilgen, property.Name, property.PropertyType); MethodInfo method = property.GetSetMethod(); + + if (method == null) + { + string message = string.Format("Could not find a Setter for property {0} of type {1}", property.Name, + property.DeclaringType.FullName); + throw new ApplicationException(message); + } + ilgen.Emit(OpCodes.Callvirt, method); } } Modified: trunk/Source/StructureMap/Graph/Plugin.cs =================================================================== --- trunk/Source/StructureMap/Graph/Plugin.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap/Graph/Plugin.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Reflection; using StructureMap.Pipeline; @@ -147,5 +148,16 @@ return templatedPlugin; } + + public void SetFilledTypes(IList<Type> types) + { + foreach (SetterProperty setter in _setters) + { + if (types.Contains(setter.Property.PropertyType)) + { + setter.IsMandatory = true; + } + } + } } } \ No newline at end of file Added: trunk/Source/StructureMap/Graph/PluginCache.cs =================================================================== --- trunk/Source/StructureMap/Graph/PluginCache.cs (rev 0) +++ trunk/Source/StructureMap/Graph/PluginCache.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using StructureMap.Emitting; +using StructureMap.Util; + +namespace StructureMap.Graph +{ + public static class PluginCache + { + private static readonly Cache<Type, InstanceBuilder> _builders; + private static readonly Cache<Type, Plugin> _plugins; + private static List<Type> _filledTypes = new List<Type>(); + + static PluginCache() + { + _plugins = new Cache<Type, Plugin>(t => new Plugin(t)); + _builders = new Cache<Type, InstanceBuilder>(t => + { + Plugin plugin = _plugins.Retrieve(t); + plugin.SetFilledTypes(_filledTypes); + return new InstanceBuilderAssembly(new[] {plugin}).Compile()[0]; + }); + } + + public static Plugin GetPlugin(Type pluggedType) + { + return _plugins.Retrieve(pluggedType); + } + + public static InstanceBuilder FindBuilder(Type pluggedType) + { + return _builders.Retrieve(pluggedType); + } + + public static void Compile() + { + lock (typeof (PluginCache)) + { + IEnumerable<Plugin> plugins = _plugins.Where(plugin => pluginHasNoBuilder(plugin) && plugin.CanBeCreated()); + createAndStoreBuilders(plugins); + } + } + + private static void createAndStoreBuilders(IEnumerable<Plugin> plugins) + { + foreach (Plugin plugin in plugins) + { + plugin.SetFilledTypes(_filledTypes); + } + + var assembly = new InstanceBuilderAssembly(plugins); + assembly.Compile().ForEach(b => _builders.Store(b.PluggedType, b)); + } + + private static bool pluginHasNoBuilder(Plugin plugin) + { + return !_builders.Has(plugin.PluggedType); + } + + public static void Store(Type pluggedType, InstanceBuilder builder) + { + _builders.Store(pluggedType, builder); + } + + internal static void ResetAll() + { + lock (typeof(PluginCache)) + { + _builders.Clear(); + _plugins.Clear(); + } + } + + public static void AddFilledType(Type type) + { + _filledTypes.Add(type); + } + } +} \ No newline at end of file Modified: trunk/Source/StructureMap/Graph/PluginGraph.cs =================================================================== --- trunk/Source/StructureMap/Graph/PluginGraph.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap/Graph/PluginGraph.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -23,7 +23,8 @@ private readonly ProfileManager _profileManager = new ProfileManager(); private readonly bool _useExternalRegistries = true; private bool _sealed = false; - private List<Registry> _registries = new List<Registry>(); + private readonly List<Registry> _registries = new List<Registry>(); + /// <summary> @@ -111,6 +112,8 @@ _profileManager.Seal(this); + + _sealed = true; } Modified: trunk/Source/StructureMap/Graph/SetterPropertyCollection.cs =================================================================== --- trunk/Source/StructureMap/Graph/SetterPropertyCollection.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap/Graph/SetterPropertyCollection.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -23,7 +23,7 @@ foreach (PropertyInfo property in plugin.PluggedType.GetProperties()) { - if (property.CanWrite) + if (property.CanWrite && property.GetSetMethod(false) != null) { SetterProperty setter = new SetterProperty(property); _properties.Add(setter); Modified: trunk/Source/StructureMap/ObjectFactory.cs =================================================================== --- trunk/Source/StructureMap/ObjectFactory.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap/ObjectFactory.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -218,8 +218,6 @@ Container container = new Container(graph); container.SetDefaultsToProfile(_profile); - PluginCache.Compile(); - return container; } Modified: trunk/Source/StructureMap.Testing/Graph/PluginTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/PluginTester.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap.Testing/Graph/PluginTester.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Reflection; using NUnit.Framework; using Rhino.Mocks; @@ -323,6 +324,50 @@ { new Plugin(typeof(ClassWithNoConstructor)).CanBeCreated().ShouldBeFalse(); } + + public class ClassWithProperties + { + public IEngine Engine { get; set; } + public IAutomobile Car { get; set; } + public IGateway Gateway { get; set; } + } + + [Test] + public void SetFilledTypes_1() + { + Plugin plugin = new Plugin(typeof(ClassWithProperties)); + plugin.SetFilledTypes(new List<Type>() {typeof (IEngine), typeof (IAutomobile)}); + + plugin.Setters.IsMandatory("Engine").ShouldBeTrue(); + plugin.Setters.IsMandatory("Car").ShouldBeTrue(); + plugin.Setters.IsMandatory("Gateway").ShouldBeFalse(); + } + + + [Test] + public void SetFilledTypes_2() + { + Plugin plugin = new Plugin(typeof(ClassWithProperties)); + plugin.SetFilledTypes(new List<Type>() { typeof(IGateway), typeof(IAutomobile) }); + + plugin.Setters.IsMandatory("Engine").ShouldBeFalse(); + plugin.Setters.IsMandatory("Car").ShouldBeTrue(); + plugin.Setters.IsMandatory("Gateway").ShouldBeTrue(); + } + + + + [Test] + public void SetFilledTypes_3() + { + Plugin plugin = new Plugin(typeof(ClassWithProperties)); + plugin.SetFilledTypes(new List<Type>() { typeof(IGateway)}); + + plugin.Setters.IsMandatory("Engine").ShouldBeFalse(); + plugin.Setters.IsMandatory("Car").ShouldBeFalse(); + plugin.Setters.IsMandatory("Gateway").ShouldBeTrue(); + } + } public class LotsOfStuff @@ -406,8 +451,12 @@ _breed = breed; _engine = engine; } + + } + + [Pluggable("Mustang")] public class Mustang : IAutomobile { Modified: trunk/Source/StructureMap.Testing/Pipeline/OptionalSetterInjectionTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Pipeline/OptionalSetterInjectionTester.cs 2008-08-11 01:56:24 UTC (rev 137) +++ trunk/Source/StructureMap.Testing/Pipeline/OptionalSetterInjectionTester.cs 2008-08-13 21:51:26 UTC (rev 138) @@ -179,6 +179,17 @@ } [Test] + public void using_the_FillAllPropertiesOf() + { + var container = + new Container( + r => + r.FillAllPropertiesOfType<Rule>().TheDefaultIs(new ColorRule("Red"))); + + container.GetInstance<ClassWithDependency>().Rule.ShouldBeOfType(typeof(ColorRule)); + } + + [Test] public void one_optional_child_array_setter() { var container = new Container(r => r.ForRequestedType<ClassWithDependency>().TheDefaultIs( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |