From: <jer...@us...> - 2009-02-01 18:35:45
|
Revision: 230 http://structuremap.svn.sourceforge.net/structuremap/?rev=230&view=rev Author: jeremydmiller Date: 2009-02-01 18:34:03 +0000 (Sun, 01 Feb 2009) Log Message: ----------- applying patches, and fixing HttpSession outside of HttpContext Modified Paths: -------------- trunk/Source/StructureMap/Attributes/InstanceScope.cs trunk/Source/StructureMap/BuildSession.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs trunk/Source/StructureMap/Graph/PluginFamily.cs trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs trunk/Source/StructureMap/StructureMap.csproj trunk/Source/StructureMap/Util/Cache.cs trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap/Pipeline/HttpSessionBuildPolicy.cs trunk/Source/StructureMap/Pipeline/SessionWrapper.cs trunk/Source/StructureMap/Pipeline/UniquePerRequestInterceptor.cs trunk/Source/StructureMap.Testing/Bugs/HttpSessionNullRefBug.cs trunk/Source/StructureMap.Testing/PerRequestInterceptorTester.cs Property Changed: ---------------- trunk/Source/StructureMap/ Property changes on: trunk/Source/StructureMap ___________________________________________________________________ Modified: svn:ignore - bin obj *.suo *.csproj.user StructureMap.xml + bin obj *.suo *.csproj.user StructureMap.xml [Bb]in [Dd]ebug [Rr]elease *.user *.aps *.eto Modified: trunk/Source/StructureMap/Attributes/InstanceScope.cs =================================================================== --- trunk/Source/StructureMap/Attributes/InstanceScope.cs 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap/Attributes/InstanceScope.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -7,6 +7,7 @@ ThreadLocal, HttpContext, Hybrid, - HttpSession + HttpSession, + HybridHttpSession } } \ No newline at end of file Modified: trunk/Source/StructureMap/BuildSession.cs =================================================================== --- trunk/Source/StructureMap/BuildSession.cs 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap/BuildSession.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -73,7 +73,7 @@ { private readonly BuildStack _buildStack = new BuildStack(); private readonly InstanceCache _cache = new InstanceCache(); - private readonly Cache<Type, object> _defaults; + private readonly Cache<Type, Func<object>> _defaults; private readonly InterceptorLibrary _interceptorLibrary; private readonly PipelineGraph _pipelineGraph; @@ -82,7 +82,7 @@ _pipelineGraph = pipelineGraph; _interceptorLibrary = interceptorLibrary; - _defaults = new Cache<Type, object>(t => + _defaults = new Cache<Type, Func<object>>(t => { Instance instance = _pipelineGraph.GetDefault(t); @@ -91,7 +91,9 @@ throw new StructureMapException(202, t); } - return CreateInstance(t, instance); + object createdInstance = CreateInstance(t, instance); + + return () => createdInstance; }); } @@ -197,7 +199,7 @@ public virtual object CreateInstance(Type pluginType) { - return _defaults[pluginType]; + return _defaults[pluginType](); } public virtual object ApplyInterception(Type pluginType, object actualValue) @@ -208,14 +210,19 @@ public virtual void RegisterDefault(Type pluginType, object defaultObject) { - _defaults[pluginType] = defaultObject; + RegisterDefault(pluginType, () => defaultObject); } + public virtual void RegisterDefault(Type pluginType, Func<object> creator) + { + _defaults[pluginType] = creator; + } + public T TryGetInstance<T>() where T : class { if (_defaults.Has(typeof(T))) { - return (T) _defaults[typeof (T)]; + return (T) _defaults[typeof (T)](); } return _pipelineGraph.HasDefaultForPluginType(typeof (T)) @@ -234,4 +241,4 @@ return _pipelineGraph.ForType(pluginType); } } -} \ No newline at end of file +} Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -301,5 +301,10 @@ family.DefaultInstanceKey = instance.Name; }); } + + public CreatePluginFamilyExpression<PLUGINTYPE> AlwaysUnique() + { + return InterceptConstructionWith(new UniquePerRequestInterceptor()); + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Graph/PluginFamily.cs =================================================================== --- trunk/Source/StructureMap/Graph/PluginFamily.cs 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap/Graph/PluginFamily.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -79,8 +79,12 @@ break; case InstanceScope.HttpSession: - AddInterceptor(new HttpSessionBuildPolicy()); + AddInterceptor(new HybridSessionBuildPolicy()); break; + + case InstanceScope.HybridHttpSession: + AddInterceptor(new HybridSessionBuildPolicy()); + break; } } Modified: trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -1,7 +1,5 @@ -using System; using System.Collections; using System.Web; -using System.Web.SessionState; using StructureMap.Attributes; namespace StructureMap.Pipeline @@ -10,6 +8,7 @@ { public static readonly string ITEM_NAME = "STRUCTUREMAP-INSTANCES"; + public static bool HasContext() { return HttpContext.Current != null; @@ -56,107 +55,4 @@ return InstanceScope.HttpContext.ToString(); } } - - public class HttpSessionBuildPolicy : HttpContextBuildPolicy - { - protected override IDictionary findHttpDictionary() - { - return new SessionWrapper(HttpContext.Current.Session); - } - - public override string ToString() - { - return InstanceScope.HttpSession.ToString(); - } - } - - public class SessionWrapper : IDictionary - { - private readonly HttpSessionState _session; - - public SessionWrapper(HttpSessionState session) - { - _session = session; - } - - #region IDictionary Members - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public void CopyTo(Array array, int index) - { - _session.CopyTo(array, index); - } - - public int Count - { - get { return _session.Count; } - } - - public object SyncRoot - { - get { return _session.SyncRoot; } - } - - public bool IsSynchronized - { - get { return _session.IsSynchronized; } - } - - public bool Contains(object key) - { - return _session[key.ToString()] != null; - } - - public void Add(object key, object value) - { - _session.Add(key.ToString(), value); - } - - public void Clear() - { - _session.Clear(); - } - - public IDictionaryEnumerator GetEnumerator() - { - throw new NotImplementedException(); - } - - public void Remove(object key) - { - _session.Remove(key.ToString()); - } - - public object this[object key] - { - get { return _session[key.ToString()]; } - set { _session[key.ToString()] = value; } - } - - public ICollection Keys - { - get { return _session.Keys; } - } - - public ICollection Values - { - get { throw new NotImplementedException(); } - } - - public bool IsReadOnly - { - get { return _session.IsReadOnly; } - } - - public bool IsFixedSize - { - get { return false; } - } - - #endregion - } } Added: trunk/Source/StructureMap/Pipeline/HttpSessionBuildPolicy.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/HttpSessionBuildPolicy.cs (rev 0) +++ trunk/Source/StructureMap/Pipeline/HttpSessionBuildPolicy.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -0,0 +1,32 @@ +using System.Collections; +using System.Web; +using StructureMap.Attributes; + +namespace StructureMap.Pipeline +{ + public class HttpSessionBuildPolicy : HttpContextBuildPolicy + { + protected override IDictionary findHttpDictionary() + { + return new SessionWrapper(HttpContext.Current.Session); + } + + public override string ToString() + { + return InstanceScope.HttpSession.ToString(); + } + } + + public class HybridSessionBuildPolicy : HttpBuildPolicyBase<HttpSessionBuildPolicy, ThreadLocalStoragePolicy> + { + public override IBuildPolicy Clone() + { + return new HybridSessionBuildPolicy() { InnerPolicy = InnerPolicy.Clone() }; + } + + public override string ToString() + { + return InstanceScope.HybridHttpSession.ToString(); + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Pipeline/SessionWrapper.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/SessionWrapper.cs (rev 0) +++ trunk/Source/StructureMap/Pipeline/SessionWrapper.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -0,0 +1,96 @@ +using System; +using System.Collections; +using System.Web.SessionState; + +namespace StructureMap.Pipeline +{ + public class SessionWrapper : IDictionary + { + private readonly HttpSessionState _session; + + public SessionWrapper(HttpSessionState session) + { + _session = session; + } + + #region IDictionary Members + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void CopyTo(Array array, int index) + { + _session.CopyTo(array, index); + } + + public int Count + { + get { return _session.Count; } + } + + public object SyncRoot + { + get { return _session.SyncRoot; } + } + + public bool IsSynchronized + { + get { return _session.IsSynchronized; } + } + + public bool Contains(object key) + { + return _session[key.ToString()] != null; + } + + public void Add(object key, object value) + { + _session.Add(key.ToString(), value); + } + + public void Clear() + { + _session.Clear(); + } + + public IDictionaryEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } + + public void Remove(object key) + { + _session.Remove(key.ToString()); + } + + public object this[object key] + { + get { return _session[key.ToString()]; } + set { _session[key.ToString()] = value; } + } + + public ICollection Keys + { + get { return _session.Keys; } + } + + public ICollection Values + { + get { throw new NotImplementedException(); } + } + + public bool IsReadOnly + { + get { return _session.IsReadOnly; } + } + + public bool IsFixedSize + { + get { return false; } + } + + #endregion + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Pipeline/UniquePerRequestInterceptor.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/UniquePerRequestInterceptor.cs (rev 0) +++ trunk/Source/StructureMap/Pipeline/UniquePerRequestInterceptor.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -0,0 +1,46 @@ +using System; + +namespace StructureMap.Pipeline +{ + /// <summary> + /// Makes sure that every request for this object returns a unique object + /// </summary> + public class UniquePerRequestInterceptor : IBuildInterceptor + { + + #region IBuildInterceptor Members + + private IBuildPolicy _innerPolicy = new BuildPolicy(); + + public IBuildPolicy InnerPolicy + { + get { return _innerPolicy; } + set { _innerPolicy = value; } + } + + #endregion + + #region IBuildPolicy Members + + public object Build(BuildSession buildSession, Type pluginType, Instance instance) + { + //insert a default object creator + buildSession.RegisterDefault(pluginType, () => InnerPolicy.Build(buildSession, pluginType, instance)); + + //build this object for the first time + return buildSession.CreateInstance(pluginType); + } + + public IBuildPolicy Clone() + { + return new UniquePerRequestInterceptor(); + } + + public void EjectAll() + { + InnerPolicy.EjectAll(); + } + + #endregion + } +} Modified: trunk/Source/StructureMap/StructureMap.csproj =================================================================== --- trunk/Source/StructureMap/StructureMap.csproj 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap/StructureMap.csproj 2009-02-01 18:34:03 UTC (rev 230) @@ -405,6 +405,9 @@ <Compile Include="Graph\PluggableAttributeScanner.cs" /> <Compile Include="Graph\PluginCache.cs" /> <Compile Include="Pipeline\ConditionalInstance.cs" /> + <Compile Include="Pipeline\HttpSessionBuildPolicy.cs" /> + <Compile Include="Pipeline\SessionWrapper.cs" /> + <Compile Include="Pipeline\UniquePerRequestInterceptor.cs" /> <Compile Include="TypeExtensions.cs" /> <Compile Include="IBootstrapper.cs" /> <Compile Include="InitializationExpression.cs" /> Modified: trunk/Source/StructureMap/Util/Cache.cs =================================================================== --- trunk/Source/StructureMap/Util/Cache.cs 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap/Util/Cache.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -79,7 +79,9 @@ if (!_values.ContainsKey(key)) { VALUE value = _onMissing(key); - _values.Add(key, value); + //Check to make sure that the onMissing didn't cache this already + if(!_values.ContainsKey(key)) + _values.Add(key, value); } } } @@ -203,4 +205,4 @@ _values.Clear(); } } -} \ No newline at end of file +} Added: trunk/Source/StructureMap.Testing/Bugs/HttpSessionNullRefBug.cs =================================================================== --- trunk/Source/StructureMap.Testing/Bugs/HttpSessionNullRefBug.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Bugs/HttpSessionNullRefBug.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -0,0 +1,25 @@ +using NUnit.Framework; +using StructureMap.Attributes; +using StructureMap.Testing.Widget3; + +namespace StructureMap.Testing.Bugs +{ + [TestFixture] + public class HttpSessionNullRefBug + { + [Test] + public void SetUp() + { + var container = new Container(x => + { + x.ForRequestedType<IGateway>() + .CacheBy(InstanceScope.HybridHttpSession) + .TheDefaultIsConcreteType<DefaultGateway>(); + }); + + container.GetInstance<IGateway>().ShouldNotBeNull(); + } + + + } +} \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -265,10 +265,19 @@ var family = new PluginFamily(typeof(IServiceProvider)); family.SetScopeTo(InstanceScope.HttpSession); - family.Policy.ShouldBeOfType<HttpSessionBuildPolicy>(); + family.Policy.ShouldBeOfType<HybridSessionBuildPolicy>(); } [Test] + public void set_the_scope_to_session_hybrid() + { + var family = new PluginFamily(typeof(IServiceProvider)); + family.SetScopeTo(InstanceScope.HybridHttpSession); + + family.Policy.ShouldBeOfType<HybridSessionBuildPolicy>(); + } + + [Test] public void SetScopeToSingleton() { var family = new PluginFamily(typeof (IServiceProvider)); Added: trunk/Source/StructureMap.Testing/PerRequestInterceptorTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/PerRequestInterceptorTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/PerRequestInterceptorTester.cs 2009-02-01 18:34:03 UTC (rev 230) @@ -0,0 +1,70 @@ +using NUnit.Framework; +using StructureMap.Pipeline; + +namespace StructureMap.Testing +{ + [TestFixture] + public class PerRequestInterceptorTester + { + //Think of this as a data session + public class Session + { + } + + public class Model1 + { + public Model1(Session session) + { + Session = session; + } + + public Session Session { get; set; } + } + + public class Model2 + { + public Model2(Session session) + { + Session = session; + } + + public Session Session { get; set; } + } + + //this is my shell, it needs some models + public class Shell + { + public Shell(Model1 model1, Model2 model2) + { + Model1 = model1; + Model2 = model2; + } + + public Model1 Model1 { get; set; } + public Model2 Model2 { get; set; } + } + + [Test] + public void TestObjectReturnedAreUnique() + { + ObjectFactory.Initialize( + x => + { + x.BuildInstancesOf<Session>() + .AlwaysUnique() + .TheDefaultIsConcreteType<Session>(); + x.BuildInstancesOf<Model1>() + .TheDefaultIsConcreteType<Model1>(); + x.BuildInstancesOf<Model2>() + .TheDefaultIsConcreteType<Model2>(); + x.BuildInstancesOf<Shell>() + .TheDefaultIsConcreteType<Shell>(); + }); + + var shell = ObjectFactory.GetInstance<Shell>(); + + shell.Model1.Session.ShouldNotBeTheSameAs(shell.Model2.Session); + + } + } +} \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-02-01 17:47:12 UTC (rev 229) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-02-01 18:34:03 UTC (rev 230) @@ -178,6 +178,7 @@ <Compile Include="AutoMocking\RhinoMockRepositoryProxyTester.cs" /> <Compile Include="AutoWiringExamples.cs" /> <Compile Include="Bugs\BuildUpBug.cs" /> + <Compile Include="Bugs\HttpSessionNullRefBug.cs" /> <Compile Include="Bugs\IDictionaryAndXmlBugTester.cs" /> <Compile Include="Bugs\ScanIndexerBugTester.cs" /> <Compile Include="Bugs\SingletonShouldBeLazy.cs" /> @@ -373,6 +374,7 @@ <Compile Include="TestData\DataMother.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="PerRequestInterceptorTester.cs" /> <Compile Include="TestUtility.cs" /> <Compile Include="Diagnostics\ValidationBuildSessionTester.cs" /> <Compile Include="TypeExtensionsTester.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |