From: <jer...@us...> - 2008-01-14 03:57:50
|
Revision: 53 http://structuremap.svn.sourceforge.net/structuremap/?rev=53&view=rev Author: jeremydmiller Date: 2008-01-13 19:57:47 -0800 (Sun, 13 Jan 2008) Log Message: ----------- type interception for some AOP support Modified Paths: -------------- trunk/Source/StructureMap/Configuration/DSL/MementoBuilder.cs trunk/Source/StructureMap/Configuration/DSL/Registry.cs trunk/Source/StructureMap/Graph/PluginGraph.cs trunk/Source/StructureMap/IInstanceFactory.cs trunk/Source/StructureMap/InstanceFactory.cs trunk/Source/StructureMap/InstanceManager.cs trunk/Source/StructureMap/InstanceMemento.cs trunk/Source/StructureMap/StructureMap.csproj trunk/Source/StructureMap.Testing/Container/InstanceFactoryTester.cs trunk/Source/StructureMap.Testing/InstanceMementoTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap/Interceptors/CompoundInterceptor.cs trunk/Source/StructureMap/Interceptors/EnrichmentInterceptor.cs trunk/Source/StructureMap/Interceptors/InstanceInterceptor.cs trunk/Source/StructureMap/Interceptors/InterceptorLibrary.cs trunk/Source/StructureMap/Interceptors/Interceptors.cs trunk/Source/StructureMap/Interceptors/NulloInterceptor.cs trunk/Source/StructureMap/Interceptors/StartupInterceptor.cs trunk/Source/StructureMap/Interceptors/TypeInterceptor.cs trunk/Source/StructureMap.Testing/Container/Interceptors/CompoundInterceptorTester.cs trunk/Source/StructureMap.Testing/Container/Interceptors/InterceptorLibraryTester.cs trunk/Source/StructureMap.Testing/Container/Interceptors/MockTypeInterceptor.cs trunk/Source/StructureMap.Testing/Container/Interceptors/TypeInterceptionTester.cs Removed Paths: ------------- trunk/Source/StructureMap/Delegates.cs Modified: trunk/Source/StructureMap/Configuration/DSL/MementoBuilder.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/MementoBuilder.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/Configuration/DSL/MementoBuilder.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using StructureMap.Graph; +using StructureMap.Interceptors; namespace StructureMap.Configuration.DSL { Modified: trunk/Source/StructureMap/Configuration/DSL/Registry.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using StructureMap.Graph; +using StructureMap.Interceptors; namespace StructureMap.Configuration.DSL { @@ -34,6 +35,11 @@ _expressions.Add(expression); } + internal void addExpression(PluginGraphAlteration alteration) + { + _expressions.Add(new BasicExpression(alteration)); + } + internal void ConfigurePluginGraph(PluginGraph graph) { foreach (IExpression expression in _expressions) @@ -222,5 +228,70 @@ { return new ReferenceMementoBuilder(referencedKey); } + + public void RegisterInterceptor(TypeInterceptor interceptor) + { + addExpression(delegate (PluginGraph pluginGraph) + { + pluginGraph.InterceptorLibrary.AddInterceptor(interceptor); + }); + } + + public TypeInterceptorExpression IfTypeMatches(TypeMatchDelegate match) + { + TypeInterceptorExpression expression = new TypeInterceptorExpression(match); + _expressions.Add(expression); + + return expression; + } } + + public delegate object InterceptionDelegate(object instance); + public delegate bool TypeMatchDelegate(Type type); + public class TypeInterceptorExpression : IExpression, TypeInterceptor + { + private readonly TypeMatchDelegate _match; + private InterceptionDelegate _interception; + + internal TypeInterceptorExpression(TypeMatchDelegate match) + { + _match = match; + } + + void IExpression.Configure(PluginGraph graph) + { + graph.InterceptorLibrary.AddInterceptor(this); + } + + public void InterceptWith(InterceptionDelegate interception) + { + _interception = interception; + } + + public bool MatchesType(Type type) + { + return _match(type); + } + + public object Process(object target) + { + return _interception(target); + } + } + + internal delegate void PluginGraphAlteration(PluginGraph pluginGraph); + internal class BasicExpression : IExpression + { + private readonly PluginGraphAlteration _alteration; + + internal BasicExpression(PluginGraphAlteration alteration) + { + _alteration = alteration; + } + + public void Configure(PluginGraph graph) + { + _alteration(graph); + } + } } \ No newline at end of file Deleted: trunk/Source/StructureMap/Delegates.cs =================================================================== --- trunk/Source/StructureMap/Delegates.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/Delegates.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -1,52 +0,0 @@ -namespace StructureMap -{ - public delegate T EnrichmentHandler<T>(T target); - - public delegate void StartupHandler<T>(T target); - - public interface InstanceInterceptor - { - object Process(object target); - } - - public class NulloInterceptor : InstanceInterceptor - { - public object Process(object target) - { - return target; - } - } - - public class StartupInterceptor<T> : InstanceInterceptor - { - private readonly StartupHandler<T> _handler; - - public StartupInterceptor(StartupHandler<T> handler) - { - _handler = handler; - } - - - public object Process(object target) - { - _handler((T) target); - return target; - } - } - - public class EnrichmentInterceptor<T> : InstanceInterceptor - { - private readonly EnrichmentHandler<T> _handler; - - - public EnrichmentInterceptor(EnrichmentHandler<T> handler) - { - _handler = handler; - } - - public object Process(object target) - { - return _handler((T) target); - } - } -} \ No newline at end of file Modified: trunk/Source/StructureMap/Graph/PluginGraph.cs =================================================================== --- trunk/Source/StructureMap/Graph/PluginGraph.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/Graph/PluginGraph.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Reflection; using StructureMap.Configuration.DSL; +using StructureMap.Interceptors; namespace StructureMap.Graph { @@ -14,10 +15,11 @@ [Serializable] public class PluginGraph { - private AssemblyGraphCollection _assemblies; + private readonly AssemblyGraphCollection _assemblies; private bool _sealed = false; - private PluginFamilyCollection _pluginFamilies; - private InstanceDefaultManager _defaultManager = new InstanceDefaultManager(); + private readonly PluginFamilyCollection _pluginFamilies; + private readonly InstanceDefaultManager _defaultManager = new InstanceDefaultManager(); + private readonly InterceptorLibrary _interceptorLibrary = new InterceptorLibrary(); /// <summary> @@ -116,6 +118,11 @@ get { return _defaultManager; } } + public InterceptorLibrary InterceptorLibrary + { + get { return _interceptorLibrary; } + } + /// <summary> /// Un-seals a PluginGraph. Makes the PluginGraph editable /// </summary> Modified: trunk/Source/StructureMap/IInstanceFactory.cs =================================================================== --- trunk/Source/StructureMap/IInstanceFactory.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/IInstanceFactory.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -11,8 +11,8 @@ /// <summary> /// Establishes a reference to the parent InstanceManager /// </summary> - /// <param name="Manager"></param> - void SetInstanceManager(InstanceManager Manager); + /// <param name="instanceManager"></param> + void SetInstanceManager(InstanceManager instanceManager); /// <summary> /// The CLR System.Type that the IInstanceManager builds instances Modified: trunk/Source/StructureMap/InstanceFactory.cs =================================================================== --- trunk/Source/StructureMap/InstanceFactory.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/InstanceFactory.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -6,6 +6,7 @@ using StructureMap.Configuration.DSL; using StructureMap.Emitting; using StructureMap.Graph; +using StructureMap.Interceptors; using StructureMap.Source; namespace StructureMap @@ -19,6 +20,7 @@ private readonly Dictionary<string, InstanceBuilder> _instanceBuilders; private MementoSource _source; private readonly InstanceInterceptor _interceptor = new NulloInterceptor(); + private InterceptorLibrary _interceptorLibrary = InterceptorLibrary.Empty; #region static constructors @@ -123,18 +125,19 @@ /// <summary> /// Links the child InstanceBuilder members to the parent InstanceManager /// </summary> - /// <param name="Manager"></param> - public void SetInstanceManager(InstanceManager Manager) + /// <param name="instanceManager"></param> + public void SetInstanceManager(InstanceManager instanceManager) { + _interceptorLibrary = instanceManager.InterceptorLibrary; foreach (InstanceBuilder builder in _instanceBuilders.Values) { - builder.SetInstanceManager(Manager); + builder.SetInstanceManager(instanceManager); } } #region create instance builders - private void processPlugins(Plugin[] plugins) + private void processPlugins(IEnumerable<Plugin> plugins) { Assembly assembly = createInstanceBuilderAssembly(plugins); foreach (Plugin plugin in plugins) @@ -143,7 +146,7 @@ } } - private Assembly createInstanceBuilderAssembly(Plugin[] plugins) + private Assembly createInstanceBuilderAssembly(IEnumerable<Plugin> plugins) { string assemblyName = Guid.NewGuid().ToString().Replace(".", "") + "InstanceBuilderAssembly"; InstanceBuilderAssembly builderAssembly = new InstanceBuilderAssembly(assemblyName, PluginType); @@ -218,17 +221,15 @@ object IInstanceCreator.BuildInstance(InstanceMemento memento) { - if (!_instanceBuilders.ContainsKey(memento.ConcreteKey)) - { - throw new StructureMapException( - 201, memento.ConcreteKey, memento.InstanceKey, PluginType.FullName); - } + assertThatTheConcreteKeyExists(memento); - InstanceBuilder builder = _instanceBuilders[memento.ConcreteKey]; try { - return builder.BuildInstance(memento); + InstanceBuilder builder = _instanceBuilders[memento.ConcreteKey]; + object constructedInstance = builder.BuildInstance(memento); + CompoundInterceptor interceptor = _interceptorLibrary.FindInterceptor(constructedInstance.GetType()); + return interceptor.Process(constructedInstance); } catch (StructureMapException) { @@ -244,7 +245,16 @@ } } + private void assertThatTheConcreteKeyExists(InstanceMemento memento) + { + if (!_instanceBuilders.ContainsKey(memento.ConcreteKey)) + { + throw new StructureMapException( + 201, memento.ConcreteKey, memento.InstanceKey, PluginType.FullName); + } + } + /// <summary> /// Builds a new instance of the default instance of the PluginType /// </summary> Modified: trunk/Source/StructureMap/InstanceManager.cs =================================================================== --- trunk/Source/StructureMap/InstanceManager.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/InstanceManager.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -4,6 +4,7 @@ using StructureMap.Configuration.DSL; using StructureMap.Exceptions; using StructureMap.Graph; +using StructureMap.Interceptors; namespace StructureMap { @@ -12,10 +13,11 @@ /// </summary> public class InstanceManager : IInstanceManager, IEnumerable { - private Dictionary<Type, IInstanceFactory> _factories; - private bool _failOnException = true; - private GenericsPluginGraph _genericsGraph; - private InstanceDefaultManager _defaultManager; + private readonly Dictionary<Type, IInstanceFactory> _factories; + private readonly bool _failOnException = true; + private readonly GenericsPluginGraph _genericsGraph; + private readonly InstanceDefaultManager _defaultManager; + private readonly InterceptorLibrary _interceptorLibrary; /// <summary> /// Default constructor @@ -24,6 +26,7 @@ { _factories = new Dictionary<Type, IInstanceFactory>(); _genericsGraph = new GenericsPluginGraph(); + _interceptorLibrary = new InterceptorLibrary(); } /// <summary> @@ -46,6 +49,7 @@ { _failOnException = failOnException; _defaultManager = pluginGraph.DefaultManager; + _interceptorLibrary = pluginGraph.InterceptorLibrary; if (!pluginGraph.IsSealed) { @@ -70,6 +74,12 @@ get { return _defaultManager; } } + + public InterceptorLibrary InterceptorLibrary + { + get { return _interceptorLibrary; } + } + private IInstanceFactory registerPluginFamily(PluginFamily family) { InstanceFactory factory = new InstanceFactory(family, _failOnException); Modified: trunk/Source/StructureMap/InstanceMemento.cs =================================================================== --- trunk/Source/StructureMap/InstanceMemento.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/InstanceMemento.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -2,6 +2,7 @@ using StructureMap.Configuration; using StructureMap.Configuration.Tokens; using StructureMap.Graph; +using StructureMap.Interceptors; namespace StructureMap { Added: trunk/Source/StructureMap/Interceptors/CompoundInterceptor.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/CompoundInterceptor.cs (rev 0) +++ trunk/Source/StructureMap/Interceptors/CompoundInterceptor.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace StructureMap.Interceptors +{ + public class CompoundInterceptor : InstanceInterceptor + { + private readonly InstanceInterceptor[] _interceptors; + + public CompoundInterceptor(InstanceInterceptor[] interceptors) + { + _interceptors = interceptors; + } + + public object Process(object target) + { + object returnValue = target; + foreach (InstanceInterceptor interceptor in _interceptors) + { + returnValue = interceptor.Process(returnValue); + } + + return returnValue; + } + + + public InstanceInterceptor[] Interceptors + { + get { return _interceptors; } + } + } +} Added: trunk/Source/StructureMap/Interceptors/EnrichmentInterceptor.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/EnrichmentInterceptor.cs (rev 0) +++ trunk/Source/StructureMap/Interceptors/EnrichmentInterceptor.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,18 @@ +namespace StructureMap.Interceptors +{ + public class EnrichmentInterceptor<T> : InstanceInterceptor + { + private readonly EnrichmentHandler<T> _handler; + + + public EnrichmentInterceptor(EnrichmentHandler<T> handler) + { + _handler = handler; + } + + public object Process(object target) + { + return _handler((T)target); + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Interceptors/InstanceInterceptor.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/InstanceInterceptor.cs (rev 0) +++ trunk/Source/StructureMap/Interceptors/InstanceInterceptor.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,7 @@ +namespace StructureMap.Interceptors +{ + public interface InstanceInterceptor + { + object Process(object target); + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Interceptors/InterceptorLibrary.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/InterceptorLibrary.cs (rev 0) +++ trunk/Source/StructureMap/Interceptors/InterceptorLibrary.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +namespace StructureMap.Interceptors +{ + public class InterceptorLibrary + { + public static readonly InterceptorLibrary Empty = new InterceptorLibrary(); + + private readonly Dictionary<Type, CompoundInterceptor> _analyzedInterceptors + = new Dictionary<Type, CompoundInterceptor>(); + + private readonly List<TypeInterceptor> _interceptors = new List<TypeInterceptor>(); + private readonly object _locker = new object(); + + public void AddInterceptor(TypeInterceptor interceptor) + { + _interceptors.Add(interceptor); + } + + public CompoundInterceptor FindInterceptor(Type type) + { + if (_analyzedInterceptors.ContainsKey(type)) + { + return _analyzedInterceptors[type]; + } + + lock (_locker) + { + if (!_analyzedInterceptors.ContainsKey(type)) + { + TypeInterceptor[] interceptorArray = + _interceptors.FindAll(delegate(TypeInterceptor i) { return i.MatchesType(type); }).ToArray(); + _analyzedInterceptors.Add(type, new CompoundInterceptor(interceptorArray)); + } + } + + return _analyzedInterceptors[type]; + } + + public InstanceInterceptor[] FindInterceptors(Type type) + { + return FindInterceptor(type).Interceptors; + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Interceptors/Interceptors.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/Interceptors.cs (rev 0) +++ trunk/Source/StructureMap/Interceptors/Interceptors.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,6 @@ +namespace StructureMap.Interceptors +{ + public delegate T EnrichmentHandler<T>(T target); + + public delegate void StartupHandler<T>(T target); +} Added: trunk/Source/StructureMap/Interceptors/NulloInterceptor.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/NulloInterceptor.cs (rev 0) +++ trunk/Source/StructureMap/Interceptors/NulloInterceptor.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,10 @@ +namespace StructureMap.Interceptors +{ + public class NulloInterceptor : InstanceInterceptor + { + public object Process(object target) + { + return target; + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Interceptors/StartupInterceptor.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/StartupInterceptor.cs (rev 0) +++ trunk/Source/StructureMap/Interceptors/StartupInterceptor.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,19 @@ +namespace StructureMap.Interceptors +{ + public class StartupInterceptor<T> : InstanceInterceptor + { + private readonly StartupHandler<T> _handler; + + public StartupInterceptor(StartupHandler<T> handler) + { + _handler = handler; + } + + + public object Process(object target) + { + _handler((T)target); + return target; + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Interceptors/TypeInterceptor.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/TypeInterceptor.cs (rev 0) +++ trunk/Source/StructureMap/Interceptors/TypeInterceptor.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,9 @@ +using System; + +namespace StructureMap.Interceptors +{ + public interface TypeInterceptor : InstanceInterceptor + { + bool MatchesType(Type type); + } +} \ No newline at end of file Modified: trunk/Source/StructureMap/StructureMap.csproj =================================================================== --- trunk/Source/StructureMap/StructureMap.csproj 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap/StructureMap.csproj 2008-01-14 03:57:47 UTC (rev 53) @@ -335,7 +335,6 @@ <SubType>Code</SubType> </Compile> <Compile Include="ConstructorMemento.cs" /> - <Compile Include="Delegates.cs" /> <Compile Include="DeploymentTasks\DeploymentConfiguration.cs"> <SubType>Code</SubType> </Compile> @@ -471,6 +470,8 @@ <Compile Include="Interceptors\CacheInterceptor.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Interceptors\CompoundInterceptor.cs" /> + <Compile Include="Interceptors\EnrichmentInterceptor.cs" /> <Compile Include="Interceptors\HttpContextItemInterceptor.cs"> <SubType>Code</SubType> </Compile> @@ -483,15 +484,21 @@ <Compile Include="Interceptors\InstanceFactoryInterceptor.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Interceptors\InstanceInterceptor.cs" /> <Compile Include="Interceptors\InterceptorChainBuilder.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Interceptors\InterceptorLibrary.cs" /> + <Compile Include="Interceptors\Interceptors.cs" /> + <Compile Include="Interceptors\NulloInterceptor.cs" /> <Compile Include="Interceptors\SingletonInterceptor.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Interceptors\StartupInterceptor.cs" /> <Compile Include="Interceptors\ThreadLocalStorageInterceptor.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Interceptors\TypeInterceptor.cs" /> <Compile Include="IPluginGraphSource.cs" /> <Compile Include="MementoSource.cs"> <SubType>Code</SubType> Modified: trunk/Source/StructureMap.Testing/Container/InstanceFactoryTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Container/InstanceFactoryTester.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap.Testing/Container/InstanceFactoryTester.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -1,5 +1,6 @@ using NUnit.Framework; using StructureMap.Graph; +using StructureMap.Interceptors; using StructureMap.Source; using StructureMap.Testing.Widget; using StructureMap.Testing.Widget2; Added: trunk/Source/StructureMap.Testing/Container/Interceptors/CompoundInterceptorTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Container/Interceptors/CompoundInterceptorTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Container/Interceptors/CompoundInterceptorTester.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,46 @@ +using NUnit.Framework; +using Rhino.Mocks; +using StructureMap.Interceptors; + +namespace StructureMap.Testing.Container.Interceptors +{ + [TestFixture] + public class CompoundInterceptorTester + { + #region Setup/Teardown + + [SetUp] + public void SetUp() + { + } + + #endregion + + [Test] + public void CallAllTheInterceptors() + { + MockRepository mocks = new MockRepository(); + InstanceInterceptor interceptor1 = mocks.CreateMock<InstanceInterceptor>(); + InstanceInterceptor interceptor2 = mocks.CreateMock<InstanceInterceptor>(); + InstanceInterceptor interceptor3 = mocks.CreateMock<InstanceInterceptor>(); + InstanceInterceptor interceptor4 = mocks.CreateMock<InstanceInterceptor>(); + + Expect.Call(interceptor1.Process("0")).Return("1"); + Expect.Call(interceptor2.Process("1")).Return("2"); + Expect.Call(interceptor3.Process("2")).Return("3"); + Expect.Call(interceptor4.Process("3")).Return("4"); + + mocks.ReplayAll(); + CompoundInterceptor compoundInterceptor = new CompoundInterceptor(new InstanceInterceptor[] + { + interceptor1, + interceptor2, + interceptor3, + interceptor4 + }); + + Assert.AreEqual("4", compoundInterceptor.Process("0")); + mocks.VerifyAll(); + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap.Testing/Container/Interceptors/InterceptorLibraryTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Container/Interceptors/InterceptorLibraryTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Container/Interceptors/InterceptorLibraryTester.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,122 @@ +using System; +using NUnit.Framework; +using Rhino.Mocks; +using StructureMap.Interceptors; + +namespace StructureMap.Testing.Container.Interceptors +{ + [TestFixture] + public class InterceptorLibraryTester + { + private MockTypeInterceptor _interceptor1; + private MockTypeInterceptor _interceptor2; + private MockTypeInterceptor _interceptor3; + private MockTypeInterceptor _interceptor4; + private InterceptorLibrary _library; + + [SetUp] + public void SetUp() + { + _interceptor1 = new MockTypeInterceptor(typeof(string)); + _interceptor2 = new MockTypeInterceptor(typeof(int), typeof(double)); + _interceptor3 = new MockTypeInterceptor(typeof(string), typeof(bool)); + _interceptor4 = new MockTypeInterceptor(typeof(string), typeof(double)); + + _library = new InterceptorLibrary(); + _library.AddInterceptor(_interceptor1); + _library.AddInterceptor(_interceptor2); + _library.AddInterceptor(_interceptor3); + _library.AddInterceptor(_interceptor4); + } + + [Test] + public void Find_All_Of_The_Interceptors_For_A_Type_On_The_First_Pass() + { + Assert.AreEqual(new TypeInterceptor[]{_interceptor1, _interceptor3, _interceptor4}, _library.FindInterceptors(typeof(string))); + Assert.AreEqual(new TypeInterceptor[]{_interceptor2, _interceptor4}, _library.FindInterceptors(typeof(double))); + Assert.AreEqual(new TypeInterceptor[]{_interceptor2}, _library.FindInterceptors(typeof(int))); + Assert.AreEqual(new TypeInterceptor[]{_interceptor3}, _library.FindInterceptors(typeof(bool))); + } + + [Test] + public void Find_CompoundInterceptor_For_A_Type_On_The_First_Pass() + { + Assert.AreEqual(new TypeInterceptor[] { _interceptor1, _interceptor3, _interceptor4 }, _library.FindInterceptor(typeof(string)).Interceptors); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2, _interceptor4 }, _library.FindInterceptor(typeof(double)).Interceptors); + } + + [Test] + public void Find_All_Of_The_Interceptors_For_A_Type_On_Multiple_Passes() + { + Assert.AreEqual(new TypeInterceptor[] { _interceptor1, _interceptor3, _interceptor4 }, _library.FindInterceptors(typeof(string))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2, _interceptor4 }, _library.FindInterceptors(typeof(double))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2 }, _library.FindInterceptors(typeof(int))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor3 }, _library.FindInterceptors(typeof(bool))); + + Assert.AreEqual(new TypeInterceptor[] { _interceptor1, _interceptor3, _interceptor4 }, _library.FindInterceptors(typeof(string))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2, _interceptor4 }, _library.FindInterceptors(typeof(double))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2 }, _library.FindInterceptors(typeof(int))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor3 }, _library.FindInterceptors(typeof(bool))); + + Assert.AreEqual(new TypeInterceptor[] { _interceptor1, _interceptor3, _interceptor4 }, _library.FindInterceptors(typeof(string))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2, _interceptor4 }, _library.FindInterceptors(typeof(double))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2 }, _library.FindInterceptors(typeof(int))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor3 }, _library.FindInterceptors(typeof(bool))); + + Assert.AreEqual(new TypeInterceptor[] { _interceptor1, _interceptor3, _interceptor4 }, _library.FindInterceptors(typeof(string))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2, _interceptor4 }, _library.FindInterceptors(typeof(double))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor2 }, _library.FindInterceptors(typeof(int))); + Assert.AreEqual(new TypeInterceptor[] { _interceptor3 }, _library.FindInterceptors(typeof(bool))); + } + + + + [Test] + public void When_Interceptors_Are_Requested_For_A_Type_For_The_First_Time_The_Library_Will_Scan_All_The_TypeInterceptors() + { + MockRepository mocks = new MockRepository(); + TypeInterceptor interceptor1 = mocks.CreateMock<TypeInterceptor>(); + TypeInterceptor interceptor2 = mocks.CreateMock<TypeInterceptor>(); + TypeInterceptor interceptor3 = mocks.CreateMock<TypeInterceptor>(); + + _library.AddInterceptor(interceptor1); + _library.AddInterceptor(interceptor2); + _library.AddInterceptor(interceptor3); + + Type type = typeof (string); + Expect.Call(interceptor1.MatchesType(type)).Return(true); + Expect.Call(interceptor2.MatchesType(type)).Return(true); + Expect.Call(interceptor3.MatchesType(type)).Return(true); + + mocks.ReplayAll(); + _library.FindInterceptors(type); + mocks.VerifyAll(); + } + + [Test] + public void When_Interceptors_Are_Requested_For_The_Second_Time_The_Library_Will_NOT_Scan_The_Interceptors_Again() + { + MockRepository mocks = new MockRepository(); + TypeInterceptor interceptor1 = mocks.CreateMock<TypeInterceptor>(); + TypeInterceptor interceptor2 = mocks.CreateMock<TypeInterceptor>(); + TypeInterceptor interceptor3 = mocks.CreateMock<TypeInterceptor>(); + + _library.AddInterceptor(interceptor1); + _library.AddInterceptor(interceptor2); + _library.AddInterceptor(interceptor3); + + Type type = typeof(string); + Expect.Call(interceptor1.MatchesType(type)).Return(true); + Expect.Call(interceptor2.MatchesType(type)).Return(true); + Expect.Call(interceptor3.MatchesType(type)).Return(true); + + mocks.ReplayAll(); + _library.FindInterceptors(type); + _library.FindInterceptors(type); + _library.FindInterceptors(type); + _library.FindInterceptors(type); + _library.FindInterceptors(type); + mocks.VerifyAll(); + } + } +} Added: trunk/Source/StructureMap.Testing/Container/Interceptors/MockTypeInterceptor.cs =================================================================== --- trunk/Source/StructureMap.Testing/Container/Interceptors/MockTypeInterceptor.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Container/Interceptors/MockTypeInterceptor.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using StructureMap.Interceptors; + +namespace StructureMap.Testing.Container.Interceptors +{ + + + public class MockTypeInterceptor : TypeInterceptor + { + private readonly List<Type> _types = new List<Type>(); + private Dictionary<Type, InstanceInterceptor> _innerInterceptors = new Dictionary<Type, InstanceInterceptor>(); + + public MockTypeInterceptor(params Type[] types) + { + _types.AddRange(types); + } + + public void SetToMatch<T>() + { + _types.Add(typeof(T)); + } + + public bool MatchesType(Type type) + { + return _types.Contains(type); + } + + public object Process(object target) + { + return _innerInterceptors[target.GetType()].Process(target); + } + + public void AddHandler<T>(InterceptionDelegate<T> handler) + { + _types.Add(typeof(T)); + _innerInterceptors.Add(typeof(T), new CommonInterceptor<T>(handler)); + } + + public delegate object InterceptionDelegate<T>(T target); + public class CommonInterceptor<T> : InstanceInterceptor + { + private readonly InterceptionDelegate<T> _handler; + + public CommonInterceptor(InterceptionDelegate<T> handler) + { + _handler = handler; + } + + public object Process(object target) + { + return _handler((T) target); + } + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap.Testing/Container/Interceptors/TypeInterceptionTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Container/Interceptors/TypeInterceptionTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Container/Interceptors/TypeInterceptionTester.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -0,0 +1,108 @@ +using System; +using NUnit.Framework; +using StructureMap.Configuration.DSL; + +namespace StructureMap.Testing.Container.Interceptors +{ + [TestFixture] + public class TypeInterceptionTester : Registry + { + private Registry registry; + private IInstanceManager manager; + + [SetUp] + public void SetUp() + { + manager = null; + + // TODO: Want a shorthand for Type + registry = new Registry(); + registry.ForRequestedType<IAnInterfaceOfSomeSort>() + .AddInstance(Instance<IAnInterfaceOfSomeSort>().UsingConcreteType<RedSomething>().WithName("Red")) + .AddInstance(Instance<IAnInterfaceOfSomeSort>().UsingConcreteType<GreenSomething>().WithName("Green")) + .AddInstance(Instance<IAnInterfaceOfSomeSort>().UsingConcreteType<BlueSomething>().WithName("Blue")); + + } + + [Test] + public void If_An_Interceptor_Is_Registered_At_The_PluginGraph_It_Will_Be_Used_To_Construct_An_Instance() + { + MockTypeInterceptor interceptor = new MockTypeInterceptor(); + interceptor.AddHandler<RedSomething>( + delegate(RedSomething something) { return new WrappedSomething(something); }); + + interceptor.AddHandler<GreenSomething>( + delegate(GreenSomething something) { return new WrappedSomething2(something); }); + + registry.RegisterInterceptor(interceptor); + + assertThisIsType<BlueSomething>("Blue"); + assertThatThisIsWrappedSomething<WrappedSomething, RedSomething>("Red"); + assertThatThisIsWrappedSomething<WrappedSomething2, GreenSomething>("Green"); + } + + [Test] + public void Register_A_Type_Interceptor_By_The_Fluent_Interface() + { + registry.IfTypeMatches(delegate(Type type) { return type.Equals(typeof(BlueSomething)); }) + .InterceptWith(delegate(object rawInstance) + { + return new WrappedSomething((IAnInterfaceOfSomeSort)rawInstance); + }); + + assertThisIsType<RedSomething>("Red"); + assertThisIsType<GreenSomething>("Green"); + assertThatThisIsWrappedSomething<WrappedSomething, BlueSomething>("Blue"); + } + + private void assertThisIsType<T>(string name) + { + if (manager == null) + { + manager = registry.BuildInstanceManager(); + } + + Assert.IsInstanceOfType(typeof(T), manager.CreateInstance<IAnInterfaceOfSomeSort>(name)); + } + + private void assertThatThisIsWrappedSomething<OUTERTYPE, INNERTYPE>(string name) where OUTERTYPE : WrappedSomething + { + if (manager == null) + { + manager = registry.BuildInstanceManager(); + } + + OUTERTYPE something = (OUTERTYPE) manager.CreateInstance<IAnInterfaceOfSomeSort>(name); + Assert.IsInstanceOfType(typeof(INNERTYPE), something.Inner); + } + + public interface IAnInterfaceOfSomeSort{} + + public class RedSomething : IAnInterfaceOfSomeSort {} + public class GreenSomething : IAnInterfaceOfSomeSort {} + public class BlueSomething : IAnInterfaceOfSomeSort {} + + public class WrappedSomething : IAnInterfaceOfSomeSort + { + private readonly IAnInterfaceOfSomeSort _inner; + + public WrappedSomething(IAnInterfaceOfSomeSort inner) + { + _inner = inner; + } + + + public IAnInterfaceOfSomeSort Inner + { + get { return _inner; } + } + } + + public class WrappedSomething2 : WrappedSomething + { + public WrappedSomething2(IAnInterfaceOfSomeSort inner) : base(inner) + { + } + } + } +} Modified: trunk/Source/StructureMap.Testing/InstanceMementoTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/InstanceMementoTester.cs 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap.Testing/InstanceMementoTester.cs 2008-01-14 03:57:47 UTC (rev 53) @@ -1,5 +1,6 @@ using NUnit.Framework; using Rhino.Mocks; +using StructureMap.Interceptors; using StructureMap.Testing.Widget3; namespace StructureMap.Testing Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-01-12 03:21:32 UTC (rev 52) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-01-14 03:57:47 UTC (rev 53) @@ -313,15 +313,19 @@ <Compile Include="Container\IntegratedTester.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Container\Interceptors\CompoundInterceptorTester.cs" /> <Compile Include="Container\Interceptors\InteceptorChainBuilderTester.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Container\Interceptors\InterceptorLibraryTester.cs" /> + <Compile Include="Container\Interceptors\MockTypeInterceptor.cs" /> <Compile Include="Container\Interceptors\SingletonInterceptorTester.cs"> <SubType>Code</SubType> </Compile> <Compile Include="Container\Interceptors\ThreadLocalStorageInterceptorTester.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Container\Interceptors\TypeInterceptionTester.cs" /> <Compile Include="Container\MockingTester.cs"> <SubType>Code</SubType> </Compile> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |