Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Made factory methods work with open generics

Added a specialized TypeDictionary that handles type keys better. If a key is set as
an open generic, asking for a closed generic version of that type will return the same
result as if you asked for the original key.
  • Loading branch information...
commit e1aadefb9d7c4ca99dcdf063e39fad49cf55ce6d 1 parent 6583fe0
tkellogg authored
23 Source/StructureMap.Testing/GenericsIntegrationTester.cs
... ... @@ -1,5 +1,7 @@
  1 +using System;
1 2 using System.Collections;
2 3 using NUnit.Framework;
  4 +using NUnit.Framework.SyntaxHelpers;
3 5 using StructureMap.Graph;
4 6 using StructureMap.Testing.GenericWidgets;
5 7 using StructureMap.Testing.TestData;
@@ -144,5 +146,26 @@ public void SpecificImplementation()
144 146 Assert.IsNotNull(concept);
145 147 Assert.IsInstanceOfType(typeof (SpecificConcept), concept);
146 148 }
  149 +
  150 + interface IGenericType<T>{}
  151 + class GenericType<T> : IGenericType<T> {}
  152 + interface INonGenereic{}
  153 + class NonGeneric : INonGenereic{}
  154 +
  155 + [Test]
  156 + public void Can_use_factory_method_with_open_generics()
  157 + {
  158 + var container = new Container();
  159 + container.Configure(x => x.For(typeof (IGenericType<>)).Use(f =>
  160 + {
  161 + var generic = f.BuildStack.Current.RequestedType.GetGenericArguments()[0];
  162 + var type = typeof (GenericType<>).MakeGenericType(generic);
  163 + return Activator.CreateInstance(type);
  164 + }));
  165 +
  166 + var instance = container.GetInstance<IGenericType<string>>();
  167 + Assert.That(instance, Is.Not.Null);
  168 + Assert.That(instance, Is.InstanceOfType(typeof(GenericType<string>)));
  169 + }
147 170 }
148 171 }
1  Source/StructureMap.Testing/StructureMap.Testing.csproj
@@ -420,6 +420,7 @@
420 420 <Compile Include="Diagnostics\ValidationBuildSessionTester.cs" />
421 421 <Compile Include="TypeExtensionsTester.cs" />
422 422 <Compile Include="Util\CacheTester.cs" />
  423 + <Compile Include="Util\TypeDictionaryTester.cs" />
423 424 <Compile Include="XmlWriting\ElementChecker.cs">
424 425 <SubType>Code</SubType>
425 426 </Compile>
52 Source/StructureMap.Testing/Util/TypeDictionaryTester.cs
... ... @@ -0,0 +1,52 @@
  1 +using System;
  2 +using System.Collections.Generic;
  3 +using System.Linq;
  4 +using System.Text;
  5 +using NUnit.Framework;
  6 +using StructureMap.Util;
  7 +
  8 +namespace StructureMap.Testing.Util
  9 +{
  10 + [TestFixture]
  11 + public class TypeDictionaryTester
  12 + {
  13 + private TypeDictionary<string> _dictionary;
  14 +
  15 + #region Types used for testing
  16 +
  17 + class NonGeneric { }
  18 + class Generic<T> { }
  19 +
  20 + #endregion
  21 +
  22 + [SetUp]
  23 + public void SetUp()
  24 + {
  25 + _dictionary = new TypeDictionary<string>();
  26 + }
  27 +
  28 + [Test]
  29 + public void It_can_get_NonGeneric_key()
  30 + {
  31 + _dictionary.Add(typeof(NonGeneric), "yup");
  32 + string val = null;
  33 + Assert.That(_dictionary.TryGetValue(typeof(NonGeneric), out val));
  34 + }
  35 +
  36 + [Test]
  37 + public void It_can_get_Generic_key_directly_as_open_generic()
  38 + {
  39 + _dictionary.Add(typeof(Generic<>), "yup");
  40 + string val = null;
  41 + Assert.That(_dictionary.TryGetValue(typeof(Generic<>), out val));
  42 + }
  43 +
  44 + [Test]
  45 + public void It_can_get_Generic_key_indirectly_as_closed_generic()
  46 + {
  47 + _dictionary.Add(typeof(Generic<>), "yup");
  48 + string val = null;
  49 + Assert.That(_dictionary.TryGetValue(typeof(Generic<string>), out val));
  50 + }
  51 + }
  52 +}
5 Source/StructureMap/Pipeline/Profile.cs
... ... @@ -1,13 +1,14 @@
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using StructureMap.Graph;
  4 +using StructureMap.Util;
4 5
5 6 namespace StructureMap.Pipeline
6 7 {
7 8 public class Profile
8 9 {
9 10 private readonly string _name;
10   - private Dictionary<Type, Instance> _instances = new Dictionary<Type, Instance>();
  11 + private TypeDictionary<Instance> _instances = new TypeDictionary<Instance>();
11 12
12 13 public Profile(string name)
13 14 {
@@ -70,7 +71,7 @@ public void Merge(Profile destination)
70 71
71 72 public void FindMasterInstances(PluginGraph graph)
72 73 {
73   - var master = new Dictionary<Type, Instance>();
  74 + var master = new TypeDictionary<Instance>();
74 75
75 76 foreach (var pair in _instances)
76 77 {
5 Source/StructureMap/PipelineGraph.cs
@@ -5,6 +5,7 @@
5 5 using StructureMap.Graph;
6 6 using StructureMap.Pipeline;
7 7 using StructureMap.Query;
  8 +using StructureMap.Util;
8 9
9 10 namespace StructureMap
10 11 {
@@ -13,8 +14,8 @@ namespace StructureMap
13 14
14 15 public class PipelineGraph : IDisposable
15 16 {
16   - private readonly Dictionary<Type, IInstanceFactory> _factories
17   - = new Dictionary<Type, IInstanceFactory>();
  17 + private readonly TypeDictionary<IInstanceFactory> _factories
  18 + = new TypeDictionary<IInstanceFactory>();
18 19
19 20 private readonly GenericsPluginGraph _genericsGraph = new GenericsPluginGraph();
20 21 private readonly GraphLog _log;
1  Source/StructureMap/StructureMap.csproj
@@ -328,6 +328,7 @@
328 328 <SubType>Code</SubType>
329 329 </Compile>
330 330 <Compile Include="Diagnostics\ValidationBuildSession.cs" />
  331 + <Compile Include="Util\TypeDictionary.cs" />
331 332 <EmbeddedResource Include="StructureMapException.resx">
332 333 <SubType>Designer</SubType>
333 334 </EmbeddedResource>
41 Source/StructureMap/Util/TypeDictionary.cs
... ... @@ -0,0 +1,41 @@
  1 +using System;
  2 +using System.Collections.Generic;
  3 +
  4 +namespace StructureMap.Util
  5 +{
  6 + public class TypeDictionary<TValue> : Dictionary<Type, TValue>
  7 + {
  8 + public new bool ContainsKey(Type key)
  9 + {
  10 + TValue value;
  11 + return TryGetValue(key, out value);
  12 + }
  13 +
  14 + public new TValue this[Type type]
  15 + {
  16 + get
  17 + {
  18 + TValue value;
  19 + if (TryGetValue(type, out value))
  20 + return value;
  21 +
  22 + throw new ArgumentOutOfRangeException("type", type, "Was not found");
  23 + }
  24 + set { base[type] = value; }
  25 + }
  26 +
  27 + public new bool TryGetValue(Type key, out TValue value)
  28 + {
  29 + if (base.TryGetValue(key, out value))
  30 + return true;
  31 +
  32 + if (key.IsGenericType)
  33 + {
  34 + var genericDefinition = key.GetGenericTypeDefinition();
  35 + if (genericDefinition == null) throw new InvalidOperationException();
  36 + return base.TryGetValue(genericDefinition, out value);
  37 + }
  38 + return false;
  39 + }
  40 + }
  41 +}

0 comments on commit e1aadef

Please sign in to comment.
Something went wrong with that request. Please try again.