From: <jer...@us...> - 2009-12-27 15:59:29
|
Revision: 304 http://structuremap.svn.sourceforge.net/structuremap/?rev=304&view=rev Author: jeremydmiller Date: 2009-12-27 15:59:19 +0000 (Sun, 27 Dec 2009) Log Message: ----------- refactored and also extended the IObjectCache, MainObjectCache classes to get ready for extensions to "Model" Modified Paths: -------------- trunk/Source/StructureMap/Container.cs trunk/Source/StructureMap/Model.cs trunk/Source/StructureMap/Pipeline/ConstructorInstance.cs trunk/Source/StructureMap/Pipeline/IObjectCache.cs trunk/Source/StructureMap/Pipeline/Instance.cs trunk/Source/StructureMap/Pipeline/MainObjectCache.cs trunk/Source/StructureMap/Pipeline/NulloObjectCache.cs trunk/Source/StructureMap/StructureMap.csproj trunk/Source/StructureMap.Testing/ModelQueryTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap/IModel.cs trunk/Source/StructureMap.Testing/Pipeline/MainObjectCacheTester.cs Modified: trunk/Source/StructureMap/Container.cs =================================================================== --- trunk/Source/StructureMap/Container.cs 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap/Container.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -64,7 +64,7 @@ /// <summary> /// Provides queryable access to the configured PluginType's and Instances of this Container /// </summary> - public IModel Model { get { return new Model(_pipelineGraph); } } + public IModel Model { get { return new Model(_pipelineGraph, this); } } /// <summary> /// Creates or finds the named instance of T Added: trunk/Source/StructureMap/IModel.cs =================================================================== --- trunk/Source/StructureMap/IModel.cs (rev 0) +++ trunk/Source/StructureMap/IModel.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using StructureMap.Pipeline; + +namespace StructureMap +{ + /// <summary> + /// Models the state of a Container or ObjectFactory. Can be used to query for the + /// existence of types registered with StructureMap + /// </summary> + public interface IModel + { + /// <summary> + /// Access to all the <seealso cref="PluginTypeConfiguration">Plugin Type</seealso> registrations + /// </summary> + IEnumerable<PluginTypeConfiguration> PluginTypes { get; } + + IEnumerable<IInstance> AllInstances { get; } + + /// <summary> + /// Can StructureMap fulfill a request to ObjectFactory.GetInstance(pluginType) from the + /// current configuration. This does not include concrete classes that could be auto-configured + /// upon demand + /// </summary> + /// <param name="pluginType"></param> + /// <returns></returns> + bool HasDefaultImplementationFor(Type pluginType); + + /// <summary> + /// Can StructureMap fulfill a request to ObjectFactory.GetInstance<T>() from the + /// current configuration. This does not include concrete classes that could be auto-configured + /// upon demand + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns></returns> + bool HasDefaultImplementationFor<T>(); + + /// <summary> + /// Queryable access to all of the <see cref="IInstance">IInstance</see> for a given PluginType + /// </summary> + /// <param name="pluginType"></param> + /// <returns></returns> + IEnumerable<IInstance> InstancesOf(Type pluginType); + + /// <summary> + /// Queryable access to all of the <see cref="IInstance">IInstance</see> for a given PluginType + /// </summary> + /// <returns></returns> + IEnumerable<IInstance> InstancesOf<T>(); + + /// <summary> + /// Does the current container have existing configuration for the "pluginType" + /// </summary> + /// <param name="pluginType"></param> + /// <returns></returns> + bool HasImplementationsFor(Type pluginType); + + /// <summary> + /// Does the current container have existing configuration for the type T + /// </summary> + /// <returns></returns> + bool HasImplementationsFor<T>(); + + /// <summary> + /// Find the concrete type for the default Instance of T. + /// In other words, when I call Container.GetInstance(Type), + /// what do I get? May be indeterminate + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns></returns> + Type DefaultTypeFor<T>(); + + /// <summary> + /// Find the concrete type for the default Instance of pluginType. + /// In other words, when I call Container.GetInstance(Type), + /// what do I get? May be indeterminate + /// </summary> + /// <returns></returns> + Type DefaultTypeFor(Type pluginType); + } +} \ No newline at end of file Modified: trunk/Source/StructureMap/Model.cs =================================================================== --- trunk/Source/StructureMap/Model.cs 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap/Model.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -5,79 +5,28 @@ namespace StructureMap { - /// <summary> - /// Models the state of a Container or ObjectFactory. Can be used to query for the - /// existence of types registered with StructureMap - /// </summary> - public interface IModel - { - /// <summary> - /// Access to all the <seealso cref="PluginTypeConfiguration">Plugin Type</seealso> registrations - /// </summary> - IEnumerable<PluginTypeConfiguration> PluginTypes { get; } - - IEnumerable<IInstance> AllInstances { get; } - - /// <summary> - /// Can StructureMap fulfill a request to ObjectFactory.GetInstance(pluginType) from the - /// current configuration. This does not include concrete classes that could be auto-configured - /// upon demand - /// </summary> - /// <param name="pluginType"></param> - /// <returns></returns> - bool HasDefaultImplementationFor(Type pluginType); - - /// <summary> - /// Can StructureMap fulfill a request to ObjectFactory.GetInstance<T>() from the - /// current configuration. This does not include concrete classes that could be auto-configured - /// upon demand - /// </summary> - /// <typeparam name="T"></typeparam> - /// <returns></returns> - bool HasDefaultImplementationFor<T>(); - - /// <summary> - /// Queryable access to all of the <see cref="IInstance">IInstance</see> for a given PluginType - /// </summary> - /// <param name="pluginType"></param> - /// <returns></returns> - IEnumerable<IInstance> InstancesOf(Type pluginType); - - /// <summary> - /// Queryable access to all of the <see cref="IInstance">IInstance</see> for a given PluginType - /// </summary> - /// <returns></returns> - IEnumerable<IInstance> InstancesOf<T>(); - - /// <summary> - /// Does the current container have existing configuration for the "pluginType" - /// </summary> - /// <param name="pluginType"></param> - /// <returns></returns> - bool HasImplementationsFor(Type pluginType); - - /// <summary> - /// Does the current container have existing configuration for the type T - /// </summary> - /// <returns></returns> - bool HasImplementationsFor<T>(); - } - public class Model : IModel { private readonly PipelineGraph _graph; + private readonly IContainer _container; - internal Model(PipelineGraph graph) + internal Model(PipelineGraph graph, IContainer container) { _graph = graph; + _container = container; } #region IModel Members public bool HasDefaultImplementationFor(Type pluginType) { + return findForFamily(pluginType, f => f.Default != null); + } + + private T findForFamily<T>(Type pluginType, Func<PluginTypeConfiguration, T> func) + { PluginTypeConfiguration family = PluginTypes.FirstOrDefault(x => x.PluginType == pluginType); - return family == null ? false : family.Default != null; + return family == null ? default(T) : func(family); } public bool HasDefaultImplementationFor<T>() @@ -85,6 +34,16 @@ return HasDefaultImplementationFor(typeof (T)); } + public Type DefaultTypeFor<T>() + { + return DefaultTypeFor(typeof (T)); + } + + public Type DefaultTypeFor(Type pluginType) + { + return findForFamily(pluginType, f => f.Default == null ? null : f.Default.ConcreteType); + } + public IEnumerable<PluginTypeConfiguration> PluginTypes { get { return _graph.PluginTypes; } } public IEnumerable<IInstance> InstancesOf(Type pluginType) Modified: trunk/Source/StructureMap/Pipeline/ConstructorInstance.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/ConstructorInstance.cs 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap/Pipeline/ConstructorInstance.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -119,11 +119,6 @@ return instance; } - protected override void addTemplatedInstanceTo(PluginFamily family, Type[] templateTypes) - { - throw new NotImplementedException(); - } - protected override sealed string getDescription() { return "Configured Instance of " + _plugin.PluggedType.AssemblyQualifiedName; Modified: trunk/Source/StructureMap/Pipeline/IObjectCache.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/IObjectCache.cs 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap/Pipeline/IObjectCache.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -8,6 +8,11 @@ int Count { get; } + bool Has(Type pluginType, Instance instance); + + void Eject(Type pluginType, Instance instance); + + object Get(Type pluginType, Instance instance); void Set(Type pluginType, Instance instance, object value); void DisposeAndClear(); Modified: trunk/Source/StructureMap/Pipeline/Instance.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/Instance.cs 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap/Pipeline/Instance.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -25,9 +25,6 @@ Instance FindInstanceForProfile(PluginFamily family, string profileName, GraphLog log); InstanceToken CreateToken(); void Preprocess(PluginFamily family); - - [Obsolete("can go away")] - void AddTemplatedInstanceTo(PluginFamily family, Type[] templateTypes); } public abstract class Instance : IDiagnosticInstance @@ -73,12 +70,6 @@ preprocess(family); } - [Obsolete("Can go")] - void IDiagnosticInstance.AddTemplatedInstanceTo(PluginFamily family, Type[] templateTypes) - { - addTemplatedInstanceTo(family, templateTypes); - } - Type IInstance.ConcreteType { get { return getConcreteType(null); } } string IInstance.Description { get { return getDescription(); } } Modified: trunk/Source/StructureMap/Pipeline/MainObjectCache.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/MainObjectCache.cs 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap/Pipeline/MainObjectCache.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -1,21 +1,38 @@ using System; using System.Collections.Generic; +using StructureMap.Util; namespace StructureMap.Pipeline { public class MainObjectCache : IObjectCache { private readonly object _locker = new object(); - private readonly IDictionary<InstanceKey, object> _objects = new Dictionary<InstanceKey, object>(); + private readonly Cache<InstanceKey, object> _objects = new Cache<InstanceKey, object>(); public object Locker { get { return _locker; } } public int Count { get { return _objects.Count; } } + public bool Has(Type pluginType, Instance instance) + { + var key = new InstanceKey(instance, pluginType); + return _objects.Has(key); + } + + public void Eject(Type pluginType, Instance instance) + { + var key = new InstanceKey(instance, pluginType); + if (!_objects.Has(key)) return; + + var disposable = _objects[key] as IDisposable; + _objects.Remove(key); + disposeObject(disposable); + } + public object Get(Type pluginType, Instance instance) { var key = new InstanceKey(instance, pluginType); - return _objects.ContainsKey(key) ? _objects[key] : null; + return _objects.Has(key) ? _objects[key] : null; } public void Set(Type pluginType, Instance instance, object value) @@ -25,7 +42,7 @@ try { var key = new InstanceKey(instance, pluginType); - _objects.Add(key, value); + _objects[key] = value; } catch (ArgumentException e) { @@ -39,25 +56,29 @@ { lock (Locker) { - foreach (object @object in _objects.Values) + _objects.Each(@object => { - if (@object is Container) continue; + if (@object is Container) return; - var disposable = @object as IDisposable; - if (disposable != null) - { - try - { - disposable.Dispose(); - } - catch (Exception) - { - } - } - } + disposeObject(@object as IDisposable); + }); _objects.Clear(); } } + + private void disposeObject(IDisposable disposable) + { + if (disposable != null) + { + try + { + disposable.Dispose(); + } + catch (Exception) + { + } + } + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Pipeline/NulloObjectCache.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/NulloObjectCache.cs 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap/Pipeline/NulloObjectCache.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -8,6 +8,15 @@ public int Count { get { return 0; } } + public bool Has(Type pluginType, Instance instance) + { + return false; + } + + public void Eject(Type pluginType, Instance instance) + { + } + public object Get(Type pluginType, Instance instance) { return null; Modified: trunk/Source/StructureMap/StructureMap.csproj =================================================================== --- trunk/Source/StructureMap/StructureMap.csproj 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap/StructureMap.csproj 2009-12-27 15:59:19 UTC (rev 304) @@ -367,6 +367,7 @@ <Compile Include="Graph\PluggableAttributeScanner.cs" /> <Compile Include="Graph\PluginCache.cs" /> <Compile Include="IContext.cs" /> + <Compile Include="IModel.cs" /> <Compile Include="Pipeline\Arguments.cs" /> <Compile Include="Pipeline\ArrayCoercion.cs" /> <Compile Include="Pipeline\ConditionalInstance.cs" /> Modified: trunk/Source/StructureMap.Testing/ModelQueryTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/ModelQueryTester.cs 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap.Testing/ModelQueryTester.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -5,6 +5,7 @@ using StructureMap.Graph; using StructureMap.Testing.GenericWidgets; using StructureMap.Testing.Graph; +using StructureMap.Testing.Widget; namespace StructureMap.Testing { @@ -30,7 +31,7 @@ PluginGraph graph = registry.Build(); var pipeline = new PipelineGraph(graph); - _model = new Model(pipeline); + _model = new Container(graph).Model; _container = new Container(graph); } @@ -54,7 +55,7 @@ } - private Model _model; + private IModel _model; private Container _container; @@ -67,6 +68,16 @@ } [Test] + public void the_default_type_for() + { + _model.DefaultTypeFor<ISomething>().ShouldEqual(typeof (SomethingOne)); + _model.DefaultTypeFor<IWidget>().ShouldBeNull(); + + _model.DefaultTypeFor(typeof (IService<>)).ShouldBeNull(); + _model.DefaultTypeFor(typeof(ISomething)).ShouldEqual(typeof(SomethingOne)); + } + + [Test] public void HasImplementationFor_w_container() { _container.Model.HasDefaultImplementationFor(typeof (ISomething)).ShouldBeTrue(); @@ -74,6 +85,8 @@ _container.Model.HasDefaultImplementationFor(typeof (IServiceProvider)).ShouldBeFalse(); } + + [Test] public void HasImplementationsFor() { @@ -109,7 +122,8 @@ [Test] public void Iterate_over_pluginTypes() { - _model.PluginTypes.Count().ShouldEqual(3); + // 3 registered plus the 4th is the IContainer itself + _model.PluginTypes.Count().ShouldEqual(4); } [Test] Added: trunk/Source/StructureMap.Testing/Pipeline/MainObjectCacheTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Pipeline/MainObjectCacheTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Pipeline/MainObjectCacheTester.cs 2009-12-27 15:59:19 UTC (rev 304) @@ -0,0 +1,69 @@ +using System; +using NUnit.Framework; +using Rhino.Mocks; +using StructureMap.Pipeline; +using StructureMap.Testing.Widget; + +namespace StructureMap.Testing.Pipeline +{ + [TestFixture] + public class MainObjectCacheTester + { + private MainObjectCache cache; + + [SetUp] + public void SetUp() + { + cache = new MainObjectCache(); + } + + [Test] + public void has() + { + var widget = new AWidget(); + var instance = new ObjectInstance(widget); + + cache.Has(typeof(IWidget), instance).ShouldBeFalse(); + + cache.Set(typeof(Rule), instance, widget); + + cache.Has(typeof(IWidget), instance).ShouldBeFalse(); + + cache.Set(typeof(IWidget), new ObjectInstance(new AWidget()), widget); + + cache.Has(typeof(IWidget), instance).ShouldBeFalse(); + + cache.Set(typeof(IWidget), instance, widget); + + cache.Has(typeof(IWidget), instance).ShouldBeTrue(); + } + + [Test] + public void eject_a_disposable_object() + { + var disposable = MockRepository.GenerateMock<IDisposable>(); + var instance = new ObjectInstance(disposable); + + cache.Set(typeof(IWidget), instance, disposable); + + cache.Eject(typeof(IWidget), instance); + + cache.Has(typeof(IWidget), instance).ShouldBeFalse(); + + disposable.AssertWasCalled(x => x.Dispose()); + } + + [Test] + public void eject_a_non_disposable_object() + { + var widget = new AWidget(); + var instance = new ObjectInstance(widget); + + cache.Set(typeof(IWidget), instance, widget); + + cache.Eject(typeof(IWidget), instance); + + cache.Has(typeof(IWidget), instance).ShouldBeFalse(); + } + } +} \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-12-26 20:51:05 UTC (rev 303) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-12-27 15:59:19 UTC (rev 304) @@ -364,6 +364,7 @@ <Compile Include="Pipeline\GenericsHelperExpressionTester.cs" /> <Compile Include="Pipeline\HybridBuildLifecycleTester.cs" /> <Compile Include="Pipeline\InstanceTester.cs" /> + <Compile Include="Pipeline\MainObjectCacheTester.cs" /> <Compile Include="Pipeline\ObjectInstanceTester.cs" /> <Compile Include="Pipeline\MissingInstanceTester.cs" /> <Compile Include="Pipeline\NestedContainerSupportTester.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |