|
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.
|