Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
View
@@ -1,5 +1,7 @@
+using System;
using System.Collections;
using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
using StructureMap.Graph;
using StructureMap.Testing.GenericWidgets;
using StructureMap.Testing.TestData;
@@ -144,5 +146,26 @@ public void SpecificImplementation()
Assert.IsNotNull(concept);
Assert.IsInstanceOfType(typeof (SpecificConcept), concept);
}
+
+ interface IGenericType<T>{}
+ class GenericType<T> : IGenericType<T> {}
+ interface INonGenereic{}
+ class NonGeneric : INonGenereic{}
+
+ [Test]
+ public void Can_use_factory_method_with_open_generics()
+ {
+ var container = new Container();
+ container.Configure(x => x.For(typeof (IGenericType<>)).Use(f =>
+ {
+ var generic = f.BuildStack.Current.RequestedType.GetGenericArguments()[0];
+ var type = typeof (GenericType<>).MakeGenericType(generic);
+ return Activator.CreateInstance(type);
+ }));
+
+ var instance = container.GetInstance<IGenericType<string>>();
+ Assert.That(instance, Is.Not.Null);
+ Assert.That(instance, Is.InstanceOfType(typeof(GenericType<string>)));
+ }
}
}
1  Source/StructureMap.Testing/StructureMap.Testing.csproj
View
@@ -420,6 +420,7 @@
<Compile Include="Diagnostics\ValidationBuildSessionTester.cs" />
<Compile Include="TypeExtensionsTester.cs" />
<Compile Include="Util\CacheTester.cs" />
+ <Compile Include="Util\TypeDictionaryTester.cs" />
<Compile Include="XmlWriting\ElementChecker.cs">
<SubType>Code</SubType>
</Compile>
52 Source/StructureMap.Testing/Util/TypeDictionaryTester.cs
View
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using StructureMap.Util;
+
+namespace StructureMap.Testing.Util
+{
+ [TestFixture]
+ public class TypeDictionaryTester
+ {
+ private TypeDictionary<string> _dictionary;
+
+ #region Types used for testing
+
+ class NonGeneric { }
+ class Generic<T> { }
+
+ #endregion
+
+ [SetUp]
+ public void SetUp()
+ {
+ _dictionary = new TypeDictionary<string>();
+ }
+
+ [Test]
+ public void It_can_get_NonGeneric_key()
+ {
+ _dictionary.Add(typeof(NonGeneric), "yup");
+ string val = null;
+ Assert.That(_dictionary.TryGetValue(typeof(NonGeneric), out val));
+ }
+
+ [Test]
+ public void It_can_get_Generic_key_directly_as_open_generic()
+ {
+ _dictionary.Add(typeof(Generic<>), "yup");
+ string val = null;
+ Assert.That(_dictionary.TryGetValue(typeof(Generic<>), out val));
+ }
+
+ [Test]
+ public void It_can_get_Generic_key_indirectly_as_closed_generic()
+ {
+ _dictionary.Add(typeof(Generic<>), "yup");
+ string val = null;
+ Assert.That(_dictionary.TryGetValue(typeof(Generic<string>), out val));
+ }
+ }
+}
5 Source/StructureMap/Pipeline/Profile.cs
View
@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using StructureMap.Graph;
+using StructureMap.Util;
namespace StructureMap.Pipeline
{
public class Profile
{
private readonly string _name;
- private Dictionary<Type, Instance> _instances = new Dictionary<Type, Instance>();
+ private TypeDictionary<Instance> _instances = new TypeDictionary<Instance>();
public Profile(string name)
{
@@ -70,7 +71,7 @@ public void Merge(Profile destination)
public void FindMasterInstances(PluginGraph graph)
{
- var master = new Dictionary<Type, Instance>();
+ var master = new TypeDictionary<Instance>();
foreach (var pair in _instances)
{
5 Source/StructureMap/PipelineGraph.cs
View
@@ -5,6 +5,7 @@
using StructureMap.Graph;
using StructureMap.Pipeline;
using StructureMap.Query;
+using StructureMap.Util;
namespace StructureMap
{
@@ -13,8 +14,8 @@ namespace StructureMap
public class PipelineGraph : IDisposable
{
- private readonly Dictionary<Type, IInstanceFactory> _factories
- = new Dictionary<Type, IInstanceFactory>();
+ private readonly TypeDictionary<IInstanceFactory> _factories
+ = new TypeDictionary<IInstanceFactory>();
private readonly GenericsPluginGraph _genericsGraph = new GenericsPluginGraph();
private readonly GraphLog _log;
1  Source/StructureMap/StructureMap.csproj
View
@@ -328,6 +328,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Diagnostics\ValidationBuildSession.cs" />
+ <Compile Include="Util\TypeDictionary.cs" />
<EmbeddedResource Include="StructureMapException.resx">
<SubType>Designer</SubType>
</EmbeddedResource>
41 Source/StructureMap/Util/TypeDictionary.cs
View
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+
+namespace StructureMap.Util
+{
+ public class TypeDictionary<TValue> : Dictionary<Type, TValue>
+ {
+ public new bool ContainsKey(Type key)
+ {
+ TValue value;
+ return TryGetValue(key, out value);
+ }
+
+ public new TValue this[Type type]
+ {
+ get
+ {
+ TValue value;
+ if (TryGetValue(type, out value))
+ return value;
+
+ throw new ArgumentOutOfRangeException("type", type, "Was not found");
+ }
+ set { base[type] = value; }
+ }
+
+ public new bool TryGetValue(Type key, out TValue value)
+ {
+ if (base.TryGetValue(key, out value))
+ return true;
+
+ if (key.IsGenericType)
+ {
+ var genericDefinition = key.GetGenericTypeDefinition();
+ if (genericDefinition == null) throw new InvalidOperationException();
+ return base.TryGetValue(genericDefinition, out value);
+ }
+ return false;
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.