From: <jer...@us...> - 2009-12-19 02:29:11
|
Revision: 278 http://structuremap.svn.sourceforge.net/structuremap/?rev=278&view=rev Author: jeremydmiller Date: 2009-12-19 02:29:03 +0000 (Sat, 19 Dec 2009) Log Message: ----------- fixing a lil' bitty bug with TryGetInstance and open generic types Modified Paths: -------------- trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs trunk/Source/StructureMap/Container.cs trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs trunk/Source/StructureMap/Extensions.cs trunk/Source/StructureMap/Graph/Plugin.cs trunk/Source/StructureMap/Graph/PluginCache.cs trunk/Source/StructureMap/Pipeline/ConfiguredInstanceBase.cs trunk/Source/StructureMap/PipelineGraph.cs trunk/Source/StructureMap/TypeExtensions.cs trunk/Source/StructureMap.Testing/Pipeline/NestedContainerSupportTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap.Testing/Bugs/TryGetInstanceWithOpenGenericsBugTester.cs Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -90,6 +90,7 @@ return alterAndContinue(family => family.AddInstance(instance)); } + /// <summary> /// Sets the object creation of the instances of the PluginType. For example: PerRequest, /// Singleton, ThreadLocal, HttpContext, or Hybrid Modified: trunk/Source/StructureMap/Container.cs =================================================================== --- trunk/Source/StructureMap/Container.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/Container.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -447,7 +447,7 @@ }; // Fixes a mild bug. The child container should inject itself - container._pipelineGraph.Inject<IContainer>(container); + container.Configure(x => x.For<IContainer>().Use(container)); return container; } Modified: trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs =================================================================== --- trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Reflection; using StructureMap.Graph; +using System.Linq; namespace StructureMap.Emitting { @@ -18,10 +19,7 @@ string assemblyName = "Builders" + guidString(); _dynamicAssembly = new DynamicAssembly(assemblyName); - foreach (Plugin plugin in plugins) - { - processPlugin(plugin); - } + plugins.Where(x => x.IsNotOpenGeneric()).Each(x => processPlugin(x)); } private static string guidString() Modified: trunk/Source/StructureMap/Extensions.cs =================================================================== --- trunk/Source/StructureMap/Extensions.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/Extensions.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -7,6 +7,16 @@ { internal static class StringExtensions { + public static IEnumerable<T> Each<T>(this IEnumerable<T> enumerable, Action<T> action) + { + foreach (T target in enumerable) + { + action(target); + } + + return enumerable; + } + public static string ToFormat(this string template, params object[] parameters) { return string.Format(template, parameters); Modified: trunk/Source/StructureMap/Graph/Plugin.cs =================================================================== --- trunk/Source/StructureMap/Graph/Plugin.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/Graph/Plugin.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -3,6 +3,7 @@ using System.Linq.Expressions; using System.Reflection; using StructureMap.Pipeline; +using StructureMap.TypeRules; namespace StructureMap.Graph { @@ -165,5 +166,10 @@ { _setters.UseSetterRule(rule); } + + public bool IsNotOpenGeneric() + { + return !_pluggedType.IsGeneric(); + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Graph/PluginCache.cs =================================================================== --- trunk/Source/StructureMap/Graph/PluginCache.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/Graph/PluginCache.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -4,6 +4,7 @@ using System.Reflection; using StructureMap.Emitting; using StructureMap.Util; +using StructureMap.TypeRules; namespace StructureMap.Graph { Modified: trunk/Source/StructureMap/Pipeline/ConfiguredInstanceBase.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/ConfiguredInstanceBase.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/Pipeline/ConfiguredInstanceBase.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -202,7 +202,16 @@ { if (instance == null) return; - _children.Add(name, instance); + if (_children.ContainsKey(name)) + { + _children[name] = instance; + } + else + { + _children.Add(name, instance); + } + + } protected void setChildArray(string name, Instance[] array) Modified: trunk/Source/StructureMap/PipelineGraph.cs =================================================================== --- trunk/Source/StructureMap/PipelineGraph.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/PipelineGraph.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -4,6 +4,7 @@ using StructureMap.Diagnostics; using StructureMap.Graph; using StructureMap.Pipeline; +using StructureMap.TypeRules; namespace StructureMap { @@ -228,10 +229,13 @@ public bool HasDefaultForPluginType(Type pluginType) { - var typeToFind = pluginType.IsGenericType ? pluginType.GetGenericTypeDefinition() : pluginType; - var configuration = PluginTypes.FirstOrDefault(p => p.PluginType == typeToFind); - - return configuration == null ? false : configuration.Default != null; + var factory = ForType(pluginType); + if (_profileManager.GetDefault(pluginType) != null) + { + return true; + } + + return (factory.AllInstances.Count() == 1); } public bool HasInstance(Type pluginType, string instanceKey) Modified: trunk/Source/StructureMap/TypeExtensions.cs =================================================================== --- trunk/Source/StructureMap/TypeExtensions.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap/TypeExtensions.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -8,6 +8,17 @@ { public static class TypeExtensions { + public static bool Closes(this Type type, Type openType) + { + var baseType = type.BaseType; + if (baseType == null) return false; + + var closes = baseType.IsGenericType && baseType.GetGenericTypeDefinition() == openType; + if (closes) return true; + + return type.BaseType == null ? false : type.BaseType.Closes(openType); + } + public static bool IsInNamespace(this Type type, string nameSpace) { return type.Namespace.StartsWith(nameSpace); @@ -48,13 +59,20 @@ { if (!pluggedType.IsConcrete()) return null; - foreach (var interfaceType in pluggedType.GetInterfaces()) + if (templateType.IsInterface) { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == templateType) + foreach (var interfaceType in pluggedType.GetInterfaces()) { - return interfaceType; + if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == templateType) + { + return interfaceType; + } } } + else if (pluggedType.BaseType.IsGenericType && pluggedType.BaseType.GetGenericTypeDefinition() == templateType) + { + return pluggedType.BaseType; + } return pluggedType.BaseType == typeof(object) ? null : pluggedType.BaseType.FindInterfaceThatCloses(templateType); } @@ -183,7 +201,7 @@ public static bool IsConcrete(this Type type) { - return !type.IsAbstract; + return !type.IsAbstract && !type.IsInterface; } public static bool IsAutoFillable(this Type type) Added: trunk/Source/StructureMap.Testing/Bugs/TryGetInstanceWithOpenGenericsBugTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Bugs/TryGetInstanceWithOpenGenericsBugTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Bugs/TryGetInstanceWithOpenGenericsBugTester.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -0,0 +1,57 @@ +using System.Diagnostics; +using NUnit.Framework; +using StructureMap.TypeRules; + +namespace StructureMap.Testing.Bugs +{ + [TestFixture] + public class TryGetInstanceWithOpenGenericsBugTester + { + [SetUp] + public void SetUp() + { + } + + [Test] + public void can_get_closing_type_if_starting_from_a_base_type() + { + typeof (ClosedClass<string>).FindInterfaceThatCloses(typeof (IOpenClass<>)).ShouldEqual( + typeof (IOpenClass<string>)); + + + } + + [Test] + public void try_get_instance_fills_from_open_generic() + { + var container = new Container(x => + { + x.For(typeof(IOpenClass<>)).AddType(typeof(ClosedClass<>)); + }); + + container.TryGetInstance<IOpenClass<string>>().ShouldBeOfType<ClosedClass<string>>(); + } + + [Test] + public void try_get_instance_fills_from_open_generic_on_conventions() + { + var container = new Container(x => + { + x.Scan(o => + { + o.TheCallingAssembly(); + o.ConnectImplementationsToTypesClosing(typeof(IOpenClass<>)); + }); + }); + + Debug.WriteLine(container.WhatDoIHave()); + + container.GetInstance<IOpenClass<string>>().ShouldBeOfType<ClosedStringClass>(); + container.TryGetInstance<IOpenClass<string>>().ShouldBeOfType<ClosedStringClass>(); + } + } + + public class IOpenClass<T>{} + public class ClosedClass<T> : IOpenClass<T>{} + public class ClosedStringClass : IOpenClass<string>{} +} \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/Pipeline/NestedContainerSupportTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Pipeline/NestedContainerSupportTester.cs 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap.Testing/Pipeline/NestedContainerSupportTester.cs 2009-12-19 02:29:03 UTC (rev 278) @@ -14,7 +14,32 @@ { } + public class ContainerHolder + { + private readonly IContainer _container; + + public ContainerHolder(IContainer container) + { + _container = container; + } + + public IContainer Container { get { return _container; } } + } + [Test] + public void the_nested_container_will_deliver_itself_into_a_constructor_of_something_else() + { + var parent = new Container(x => + { + x.For<IWidget>().Use<AWidget>(); + }); + + var child = parent.GetNestedContainer(); + child.GetInstance<ContainerHolder>().Container.ShouldBeTheSameAs(child); + + } + + [Test] public void the_nested_container_delivers_itself_as_the_IContainer() { var parent = new Container(x => Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-12-05 18:40:41 UTC (rev 277) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-12-19 02:29:03 UTC (rev 278) @@ -189,6 +189,7 @@ <Compile Include="Bugs\SpecifyScopeInConfigureTester.cs" /> <Compile Include="Bugs\SpecifyScopeOnOpenGenericsTester.cs" /> <Compile Include="Bugs\StaticPropertyCausesJITExceptionTester.cs" /> + <Compile Include="Bugs\TryGetInstanceWithOpenGenericsBugTester.cs" /> <Compile Include="BuildSessionTester.cs" /> <Compile Include="BuildUpIntegratedTester.cs" /> <Compile Include="BuildUpTester.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |