From: <jer...@us...> - 2008-09-25 17:38:36
|
Revision: 155 http://structuremap.svn.sourceforge.net/structuremap/?rev=155&view=rev Author: jeremydmiller Date: 2008-09-25 17:38:24 +0000 (Thu, 25 Sep 2008) Log Message: ----------- adding some autoscan capabilities for generics Modified Paths: -------------- trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/ScanAssembliesExpression.cs trunk/Source/StructureMap/Pipeline/Instance.cs trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs trunk/Source/StructureMap.Testing/Graph/DynamicInjectionTester.cs trunk/Source/StructureMap.Testing/Graph/PluginTester.cs Removed Paths: ------------- trunk/Source/StructureMap.AutoMocking/IntegrationSpecification.cs Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2008-09-25 17:38:24 UTC (rev 155) @@ -154,7 +154,13 @@ public CreatePluginFamilyExpression<PLUGINTYPE> AddConcreteType<PLUGGEDTYPE>() { - _alterations.Add(family => family.AddInstance(new SmartInstance<PLUGGEDTYPE>())); + _alterations.Add(family => + { + string name = PluginCache.GetPlugin(typeof (PLUGGEDTYPE)).ConcreteKey; + var instance = new SmartInstance<PLUGGEDTYPE>().WithName(name); + family.AddInstance(instance); + }); + return this; } Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/ScanAssembliesExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/ScanAssembliesExpression.cs 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/ScanAssembliesExpression.cs 2008-09-25 17:38:24 UTC (rev 155) @@ -66,12 +66,24 @@ return this; } + public ScanAssembliesExpression IncludeAssemblyContainingType(Type type) + { + _assemblies.Add(type.Assembly); + + return this; + } + public ScanAssembliesExpression AddAllTypesOf<PLUGINTYPE>() { + return AddAllTypesOf(typeof (PLUGINTYPE)); + } + + public ScanAssembliesExpression AddAllTypesOf(Type pluginType) + { _registry.addExpression(pluginGraph => { PluginFamily family = - pluginGraph.FindFamily(typeof (PLUGINTYPE)); + pluginGraph.FindFamily(pluginType); family.SearchForImplicitPlugins = true; }); Modified: trunk/Source/StructureMap/Pipeline/Instance.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/Instance.cs 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap/Pipeline/Instance.cs 2008-09-25 17:38:24 UTC (rev 155) @@ -7,6 +7,15 @@ namespace StructureMap.Pipeline { + public static class TypeExtensions + { + public static ReferencedInstance GetReferenceTo(this Type type) + { + string key = PluginCache.GetPlugin(type).ConcreteKey; + return new ReferencedInstance(key); + } + } + public interface IDiagnosticInstance { bool CanBePartOfPluginFamily(PluginFamily family); Deleted: trunk/Source/StructureMap.AutoMocking/IntegrationSpecification.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/IntegrationSpecification.cs 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap.AutoMocking/IntegrationSpecification.cs 2008-09-25 17:38:24 UTC (rev 155) @@ -1,6 +0,0 @@ -namespace StructureMap.AutoMocking -{ - public class IntegrationSpecification<TARGETCLASS> - { - } -} \ No newline at end of file Modified: trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-09-25 17:38:24 UTC (rev 155) @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Reflection; using Rhino.Mocks; @@ -10,7 +11,10 @@ public delegate void VoidMethod(); - // Note that it subclasses the RhinoMocks.MockRepository class + /// <summary> + /// Provides an "Auto Mocking Container" for the concrete class TARGETCLASS + /// </summary> + /// <typeparam name="TARGETCLASS">The concrete class being tested</typeparam> public class RhinoAutoMocker<TARGETCLASS> : MockRepository where TARGETCLASS : class { private readonly AutoMockedContainer _container; @@ -18,16 +22,15 @@ public RhinoAutoMocker() { - RhinoMocksServiceLocator locator = new RhinoMocksServiceLocator(this); + var locator = new RhinoMocksServiceLocator(this); _container = new AutoMockedContainer(locator); } - // Replaces the inner Container in ObjectFactory with the mocked - // Container from the auto mocking container. This will make ObjectFactory - // return mocks for everything. Use cautiously!!!!!!!!!!!!!!! - // Gets the ClassUnderTest with mock objects (or stubs) pushed in + /// <summary> + ///Gets an instance of the ClassUnderTest with mock objects (or stubs) pushed in // for all of its dependencies + /// </summary> public TARGETCLASS ClassUnderTest { get @@ -41,13 +44,27 @@ } } + /// <summary> + /// Accesses the underlying AutoMockedContainer + /// </summary> + public AutoMockedContainer Container + { + get { return _container; } + } + + /// <summary> + /// Use this with EXTREME caution. This will replace the active "Container" in accessed + /// by ObjectFactory with the AutoMockedContainer from this instance + /// </summary> public void MockObjectFactory() { ObjectFactory.ReplaceManager(_container); } - // I find it useful from time to time to use partial mocks for the ClassUnderTest - // Especially in Presenter testing + /// <summary> + /// Calling this method will immediately create a "Partial" mock + /// for the ClassUnderTest using the "Greediest" constructor. + /// </summary> public void PartialMockTheClassUnderTest() { _classUnderTest = PartialMock<TARGETCLASS>(getConstructorArgs()); @@ -56,97 +73,123 @@ private object[] getConstructorArgs() { ConstructorInfo ctor = Constructor.GetGreediestConstructor(typeof (TARGETCLASS)); - List<object> list = new List<object>(); + var list = new List<object>(); foreach (ParameterInfo parameterInfo in ctor.GetParameters()) { Type dependencyType = parameterInfo.ParameterType; if (dependencyType.IsArray) { - var values = _container.GetAllInstances(dependencyType.GetElementType()); - var array = Array.CreateInstance(dependencyType.GetElementType(), values.Count); + IList values = _container.GetAllInstances(dependencyType.GetElementType()); + Array array = Array.CreateInstance(dependencyType.GetElementType(), values.Count); values.CopyTo(array, 0); list.Add(array); - } else { object dependency = _container.GetInstance(dependencyType); list.Add(dependency); } - - } return list.ToArray(); } - // Get one of the mock objects that are injected into the constructor function - // of the ClassUnderTest + /// <summary> + /// Gets the mock object for type T that would be injected into the constructor function + /// of the ClassUnderTest + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns></returns> public T Get<T>() { return _container.GetInstance<T>(); } - // Set the auto mocking container to use a Stub for Type T - public void InjectStub<T>(T stub) - { - _container.Inject<T>(stub); - } - + /// <summary> + /// Method to specify the exact object that will be used for + /// "pluginType." Useful for stub objects and/or static mocks + /// </summary> + /// <param name="pluginType"></param> + /// <param name="stub"></param> public void Inject(Type pluginType, object stub) { _container.Inject(pluginType, stub); } + /// <summary> + /// Method to specify the exact object that will be used for + /// "pluginType." Useful for stub objects and/or static mocks + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="target"></param> public void Inject<T>(T target) { - _container.Inject<T>(target); + _container.Inject(target); } + + /// <summary> + /// Adds an additional mock object for a given T + /// Useful for array arguments to the ClassUnderTest + /// object + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns></returns> public T AddAdditionalMockFor<T>() { - T mock = DynamicMock<T>(); + var mock = DynamicMock<T>(); _container.Configure(r => r.InstanceOf<T>().Is.Object(mock)); return mock; } - // So that Aaron Jensen can use his concrete HubService object - // Construct whatever T is with all mocks, and make sure that the - // ClassUnderTest gets built with a concrete T + + /// <summary> + /// So that Aaron Jensen can use his concrete HubService object + /// Construct whatever T is with all mocks, and make sure that the + /// ClassUnderTest gets built with a concrete T + /// </summary> + /// <typeparam name="T"></typeparam> public void UseConcreteClassFor<T>() { - T concreteClass = _container.FillDependencies<T>(); + var concreteClass = _container.FillDependencies<T>(); _container.Inject(concreteClass); } - public AutoMockedContainer Container + /// <summary> + /// Creates, returns, and registers an array of mock objects for type T. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="count"></param> + /// <returns></returns> + public T[] CreateMockArrayFor<T>(int count) { - get { return _container; } - } + var returnValue = new T[count]; - public T[] CreateMockArrayFor<T>(int count) - { - T[] returnValue = new T[count]; - for (int i = 0; i < returnValue.Length; i++) { returnValue[i] = DynamicMock<T>(); } - InjectArray<T>(returnValue); + InjectArray(returnValue); return returnValue; } + /// <summary> + /// Allows you to "inject" an array of known objects for an + /// argument of type T[] in the ClassUnderTest + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="stubs"></param> public void InjectArray<T>(T[] stubs) { _container.EjectAllInstancesOf<T>(); _container.Configure(x => { - foreach (var t in stubs) + foreach (T t in stubs) { x.InstanceOf<T>().Is.Object(t); } Modified: trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj =================================================================== --- trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-09-25 17:38:24 UTC (rev 155) @@ -67,7 +67,6 @@ <Link>CommonAssemblyInfo.cs</Link> </Compile> <Compile Include="AutoMockedContainer.cs" /> - <Compile Include="IntegrationSpecification.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="RhinoAutoMocker.cs" /> <Compile Include="RhinoMocksServiceLocator.cs" /> Modified: trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-09-25 17:38:24 UTC (rev 155) @@ -4,7 +4,6 @@ using Rhino.Mocks.Interfaces; using StructureMap.AutoMocking; using StructureMap.Graph; -using StructureMap.Testing.Widget3; namespace StructureMap.Testing.AutoMocking { @@ -135,7 +134,7 @@ public class ClassWithArray { - private IMockedService[] _services; + private readonly IMockedService[] _services; public ClassWithArray(IMockedService[] services) { @@ -149,6 +148,20 @@ } [Test] + public void AutoFillAConcreteClassWithMocks() + { + var service = _container.GetInstance<IMockedService>(); + var service2 = _container.GetInstance<IMockedService2>(); + var service3 = _container.GetInstance<IMockedService3>(); + + var concreteClass = _container.FillDependencies<ConcreteClass>(); + + Assert.AreSame(service, concreteClass.Service); + Assert.AreSame(service2, concreteClass.Service2); + Assert.AreSame(service3, concreteClass.Service3); + } + + [Test] public void CanInjectAnArrayOfMockServices1() { var mocker = new RhinoAutoMocker<ClassWithArray>(); @@ -162,7 +175,7 @@ [Test] public void CanInjectAnArrayOfMockServices2() { - var mocker = new RhinoAutoMocker<ClassWithArray>(); + var mocker = new RhinoAutoMocker<ClassWithArray>(); ClassWithArray theClass = mocker.ClassUnderTest; @@ -194,37 +207,22 @@ theClass.Services.Length.ShouldEqual(0); } - [Test] - public void AutoFillAConcreteClassWithMocks() - { - IMockedService service = _container.GetInstance<IMockedService>(); - IMockedService2 service2 = _container.GetInstance<IMockedService2>(); - IMockedService3 service3 = _container.GetInstance<IMockedService3>(); - - ConcreteClass concreteClass = _container.FillDependencies<ConcreteClass>(); - - Assert.AreSame(service, concreteClass.Service); - Assert.AreSame(service2, concreteClass.Service2); - Assert.AreSame(service3, concreteClass.Service3); - } - - [Test] public void GetAFullMockForAServiceThatHasNotPreviouslyBeenRequested() { - IMockedService service = _container.GetInstance<IMockedService>(); + var service = _container.GetInstance<IMockedService>(); Assert.IsNotNull(service); - IMockedObject instance = (IMockedObject) service; + var instance = (IMockedObject) service; Assert.AreSame(_mocks, instance.Repository); } [Test] public void GetTheSameConcreteClassTwiceFromCreate() { - RhinoAutoMocker<ConcreteClass> autoMocker = new RhinoAutoMocker<ConcreteClass>(); + var autoMocker = new RhinoAutoMocker<ConcreteClass>(); ConcreteClass concreteClass = autoMocker.ClassUnderTest; Assert.AreSame(concreteClass, autoMocker.ClassUnderTest); @@ -235,7 +233,7 @@ [Test] public void InjectAStubAndGetTheStubBack() { - StubService stub = new StubService(); + var stub = new StubService(); _container.Inject<IMockedService>(stub); Assert.AreSame(stub, _container.GetInstance<IMockedService>()); @@ -246,7 +244,7 @@ [Test] public void RequestTheServiceTwiceAndGetTheExactSameMockObject() { - IMockedService service = _container.GetInstance<IMockedService>(); + var service = _container.GetInstance<IMockedService>(); Assert.AreSame(service, _container.GetInstance<IMockedService>()); Assert.AreSame(service, _container.GetInstance<IMockedService>()); Assert.AreSame(service, _container.GetInstance<IMockedService>()); @@ -256,12 +254,12 @@ [Test] public void TheAutoMockerPushesInMocksAndAPreBuiltStubForAllOfTheConstructorArguments() { - RhinoAutoMocker<ConcreteClass> autoMocker = new RhinoAutoMocker<ConcreteClass>(); - StubService stub = new StubService(); - autoMocker.InjectStub<IMockedService>(stub); + var autoMocker = new RhinoAutoMocker<ConcreteClass>(); + var stub = new StubService(); + autoMocker.Inject<IMockedService>(stub); - IMockedService2 service2 = autoMocker.Get<IMockedService2>(); - IMockedService3 service3 = autoMocker.Get<IMockedService3>(); + var service2 = autoMocker.Get<IMockedService2>(); + var service3 = autoMocker.Get<IMockedService3>(); ConcreteClass concreteClass = autoMocker.ClassUnderTest; @@ -273,11 +271,11 @@ [Test] public void TheAutoMockerPushesInMocksForAllOfTheConstructorArgumentsForAPartialMock() { - RhinoAutoMocker<ConcreteClass> autoMocker = new RhinoAutoMocker<ConcreteClass>(); + var autoMocker = new RhinoAutoMocker<ConcreteClass>(); - IMockedService service = autoMocker.Get<IMockedService>(); - IMockedService2 service2 = autoMocker.Get<IMockedService2>(); - IMockedService3 service3 = autoMocker.Get<IMockedService3>(); + var service = autoMocker.Get<IMockedService>(); + var service2 = autoMocker.Get<IMockedService2>(); + var service3 = autoMocker.Get<IMockedService3>(); autoMocker.PartialMockTheClassUnderTest(); ConcreteClass concreteClass = autoMocker.ClassUnderTest; @@ -290,10 +288,10 @@ [Test] public void UseConcreteClassFor() { - RhinoAutoMocker<ConcreteClass> mocker = new RhinoAutoMocker<ConcreteClass>(); + var mocker = new RhinoAutoMocker<ConcreteClass>(); mocker.UseConcreteClassFor<ConcreteThing>(); - ConcreteThing thing = mocker.Get<ConcreteThing>(); + var thing = mocker.Get<ConcreteThing>(); Assert.IsInstanceOfType(typeof (ConcreteThing), thing); Assert.AreSame(mocker.Get<IMockedService>(), thing.Service); @@ -303,7 +301,7 @@ [Test] public void UseTheAutoMockerToStartUpTheConcreteClass() { - RhinoAutoMocker<ConcreteClass> autoMocker = new RhinoAutoMocker<ConcreteClass>(); + var autoMocker = new RhinoAutoMocker<ConcreteClass>(); using (autoMocker.Record()) { @@ -316,7 +314,7 @@ [Test] public void UseTheAutoMockerToStartUpTheConcreteClassAsAPartialMockAndSetTheNameMethodUp() { - RhinoAutoMocker<ConcreteClass> autoMocker = new RhinoAutoMocker<ConcreteClass>(); + var autoMocker = new RhinoAutoMocker<ConcreteClass>(); autoMocker.PartialMockTheClassUnderTest(); ConcreteClass concreteClass = autoMocker.ClassUnderTest; Modified: trunk/Source/StructureMap.Testing/Graph/DynamicInjectionTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/DynamicInjectionTester.cs 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap.Testing/Graph/DynamicInjectionTester.cs 2008-09-25 17:38:24 UTC (rev 155) @@ -97,7 +97,37 @@ Assert.IsTrue(found); } + [Test] + public void Add_an_assembly_on_the_fly_and_pick_up_plugins2() + { + var container = new Container(); + container.Configure( + registry => { registry.ScanAssemblies().IncludeAssemblyContainingType(typeof(IService<>)).AddAllTypesOf(typeof(IService<>)); }); + + IList<IService<string>> instances = container.GetAllInstances<IService<string>>(); + instances.Count.ShouldBeGreaterThan(0); + } + + + [Test] + public void Add_an_assembly_on_the_fly_and_pick_up_plugins3() + { + var container = new Container(); + container.Configure( + registry => { registry.ScanAssemblies().IncludeTheCallingAssembly().AddAllTypesOf(typeof(IWidget)); }); + + IList<IWidget> instances = container.GetAllInstances<IWidget>(); + bool found = false; + foreach (IWidget widget in instances) + { + found |= widget.GetType().Equals(typeof(TheWidget)); + } + + Assert.IsTrue(found); + } + + [Test] public void Add_generic_stuff_in_configure() { var container = new Container(); Modified: trunk/Source/StructureMap.Testing/Graph/PluginTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/PluginTester.cs 2008-09-24 21:47:17 UTC (rev 154) +++ trunk/Source/StructureMap.Testing/Graph/PluginTester.cs 2008-09-25 17:38:24 UTC (rev 155) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Reflection; using NUnit.Framework; using Rhino.Mocks; @@ -86,7 +87,18 @@ } } + [Test] + public void Can_get_the_referencedInstance_for_a_type() + { + Container container = new Container(r => r.ForRequestedType<IEngine>().AddConcreteType<DOHCEngine>()); + Debug.WriteLine(container.WhatDoIHave()); + + Instance instance = typeof (DOHCEngine).GetReferenceTo(); + + container.GetInstance<IEngine>(instance).ShouldBeOfType(typeof(DOHCEngine)); + } + [Test] public void BadPluginToAbstractClass() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |