|
From: <jer...@us...> - 2009-06-03 16:21:06
|
Revision: 247
http://structuremap.svn.sourceforge.net/structuremap/?rev=247&view=rev
Author: jeremydmiller
Date: 2009-06-03 16:21:03 +0000 (Wed, 03 Jun 2009)
Log Message:
-----------
initial work on nested containers, some little syntactical sugar in the registry DSL
Modified Paths:
--------------
trunk/Source/StructureMap/BuildSession.cs
trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs
trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs
trunk/Source/StructureMap/Configuration/DSL/Registry.cs
trunk/Source/StructureMap/Container.cs
trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs
trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs
trunk/Source/StructureMap/IContainer.cs
trunk/Source/StructureMap/IInstanceFactory.cs
trunk/Source/StructureMap/InstanceCache.cs
trunk/Source/StructureMap/InstanceFactory.cs
trunk/Source/StructureMap/Pipeline/BuildStack.cs
trunk/Source/StructureMap/Pipeline/ConfiguredInstanceBase.cs
trunk/Source/StructureMap/Pipeline/ProfileManager.cs
trunk/Source/StructureMap/PipelineGraph.cs
trunk/Source/StructureMap/StructureMap.csproj
trunk/Source/StructureMap/Util/Cache.cs
trunk/Source/StructureMap.Testing/BuildSessionTester.cs
trunk/Source/StructureMap.Testing/Graph/InstanceFactoryTester.cs
trunk/Source/StructureMap.Testing/Pipeline/ConfiguredInstanceTester.cs
trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj
trunk/Source/StructureMap.sln
Added Paths:
-----------
trunk/Source/StructureMap/Pipeline/ILifecycle.cs
trunk/Source/StructureMap/Pipeline/IObjectCache.cs
trunk/Source/StructureMap/Pipeline/Lifecycles.cs
trunk/Source/StructureMap/Pipeline/MainObjectCache.cs
trunk/Source/StructureMap/Pipeline/NulloObjectCache.cs
trunk/Source/StructureMap/Pipeline/ObjectBuilder.cs
trunk/Source/StructureMap.Testing/Pipeline/NestedContainerSupportTester.cs
trunk/Source/StructureMap.Testing/Util/
trunk/Source/StructureMap.Testing/Util/CacheTester.cs
Modified: trunk/Source/StructureMap/BuildSession.cs
===================================================================
--- trunk/Source/StructureMap/BuildSession.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/BuildSession.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -8,18 +8,17 @@
{
public class BuildSession : IContext
{
- private readonly BuildStack _buildStack = new BuildStack();
+ private BuildStack _buildStack = new BuildStack();
private readonly InstanceCache _cache = new InstanceCache();
private readonly Cache<Type, Func<object>> _defaults;
private readonly PipelineGraph _pipelineGraph;
private readonly ObjectBuilder _builder;
- public BuildSession(PipelineGraph pipelineGraph, InterceptorLibrary interceptorLibrary)
+ public BuildSession(PipelineGraph pipelineGraph, InterceptorLibrary interceptorLibrary, IObjectCache cache)
{
+ _builder = new ObjectBuilder(pipelineGraph, interceptorLibrary, cache);
_pipelineGraph = pipelineGraph;
- _builder = new ObjectBuilder(_pipelineGraph, interceptorLibrary, new NulloObjectCache());
-
_defaults = new Cache<Type, Func<object>>(t =>
{
Instance instance = _pipelineGraph.GetDefault(t);
@@ -34,7 +33,7 @@
}
public BuildSession(PluginGraph graph)
- : this(new PipelineGraph(graph), graph.InterceptorLibrary)
+ : this(new PipelineGraph(graph), graph.InterceptorLibrary, new NulloObjectCache())
{
}
@@ -43,6 +42,10 @@
{
}
+ protected void clearBuildStack()
+ {
+ _buildStack = new BuildStack();
+ }
protected PipelineGraph pipelineGraph
{
Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -103,6 +103,16 @@
}
/// <summary>
+ /// Shorthand way of saying TheDefaultIsConcreteType<>
+ /// </summary>
+ /// <typeparam name="CONCRETETYPE"></typeparam>
+ /// <returns></returns>
+ public CreatePluginFamilyExpression<PLUGINTYPE> Use<CONCRETETYPE>() where CONCRETETYPE : PLUGINTYPE
+ {
+ return TheDefaultIsConcreteType<CONCRETETYPE>();
+ }
+
+ /// <summary>
/// Sets the object creation of the instances of the PluginType. For example: PerRequest,
/// Singleton, ThreadLocal, HttpContext, or Hybrid
/// </summary>
Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -51,6 +51,16 @@
return instance;
}
+
+ /// <summary>
+ /// Shorter way to call TheDefaultIsConcreteType
+ /// </summary>
+ /// <param name="concreteType"></param>
+ /// <returns></returns>
+ public ConfiguredInstance Use(Type concreteType)
+ {
+ return TheDefaultIsConcreteType(concreteType);
+ }
/// <summary>
/// Shortcut method to add an additional Instance to this Plugin Type
Modified: trunk/Source/StructureMap/Configuration/DSL/Registry.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -47,7 +47,20 @@
void SelectConstructor<T>(Expression<Func<T>> expression);
}
+ public static class RegistryExtensions
+ {
+ public static CreatePluginFamilyExpression<PLUGINTYPE> For<PLUGINTYPE>(this IRegistry registry)
+ {
+ return registry.ForRequestedType<PLUGINTYPE>();
+ }
+ public static GenericFamilyExpression For(this IRegistry registry, Type pluginType)
+ {
+ return registry.ForRequestedType(pluginType);
+ }
+ }
+
+
/// <summary>
/// A Registry class provides methods and grammars for configuring a Container or ObjectFactory.
/// Using a Registry subclass is the recommended way of configuring a StructureMap Container.
Modified: trunk/Source/StructureMap/Container.cs
===================================================================
--- trunk/Source/StructureMap/Container.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Container.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -7,16 +7,15 @@
using StructureMap.Graph;
using StructureMap.Interceptors;
using StructureMap.Pipeline;
-using System.Linq;
namespace StructureMap
{
public class Container : TypeRules, IContainer
{
private InterceptorLibrary _interceptorLibrary;
- private Model _model;
private PipelineGraph _pipelineGraph;
private PluginGraph _pluginGraph;
+ private IObjectCache _transientCache = new NulloObjectCache();
public Container(Action<ConfigurationExpression> action)
{
@@ -26,11 +25,13 @@
construct(expression.BuildGraph());
}
- public Container(Registry registry) : this(registry.Build())
+ public Container(Registry registry)
+ : this(registry.Build())
{
}
- public Container() : this(new PluginGraph())
+ public Container()
+ : this(new PluginGraph())
{
}
@@ -44,25 +45,16 @@
construct(pluginGraph);
}
- protected MissingFactoryFunction onMissingFactory
- {
- set { _pipelineGraph.OnMissingFactory = value; }
- }
+ protected MissingFactoryFunction onMissingFactory { set { _pipelineGraph.OnMissingFactory = value; } }
+ public PluginGraph PluginGraph { get { return _pluginGraph; } }
+
#region IContainer Members
- public PluginGraph PluginGraph
- {
- get { return _pluginGraph; }
- }
-
/// <summary>
/// Provides queryable access to the configured PluginType's and Instances of this Container
/// </summary>
- public IModel Model
- {
- get { return _model; }
- }
+ public IModel Model { get { return new Model(_pipelineGraph); } }
/// <summary>
/// Creates or finds the named instance of T
@@ -110,30 +102,12 @@
public object GetInstance(Type pluginType, ExplicitArguments args)
{
Instance defaultInstance = _pipelineGraph.GetDefault(pluginType);
- var requestedName = Plugin.DEFAULT;
+ string requestedName = Plugin.DEFAULT;
return buildInstanceWithArgs(pluginType, defaultInstance, args, requestedName);
}
- private object buildInstanceWithArgs(Type pluginType, Instance defaultInstance, ExplicitArguments args, string requestedName)
- {
- if (defaultInstance == null && pluginType.IsConcrete())
- {
- defaultInstance = new ConfiguredInstance(pluginType);
- }
- BasicInstance basicInstance = defaultInstance as BasicInstance;
-
- Instance instance = basicInstance == null ? defaultInstance : new ExplicitInstance(pluginType, args, basicInstance);
-
- BuildSession session = withNewSession(requestedName);
-
- args.RegisterDefaults(session);
-
- return session.CreateInstance(pluginType, instance);
- }
-
-
/// <summary>
/// Gets all configured instances of type T using explicitly configured arguments from the "args"
/// </summary>
@@ -146,7 +120,7 @@
args.RegisterDefaults(session);
- var instances = session.CreateInstanceArray(type, null);
+ Array instances = session.CreateInstanceArray(type, null);
return new ArrayList(instances);
}
@@ -241,9 +215,9 @@
/// <returns></returns>
public object TryGetInstance(Type pluginType, string instanceKey)
{
- return !_pipelineGraph.HasInstance(pluginType, instanceKey)
- ? null
- : GetInstance(pluginType, instanceKey);
+ return !_pipelineGraph.HasInstance(pluginType, instanceKey)
+ ? null
+ : GetInstance(pluginType, instanceKey);
}
/// <summary>
@@ -253,9 +227,9 @@
/// <returns></returns>
public object TryGetInstance(Type pluginType)
{
- return !_pipelineGraph.HasDefaultForPluginType(pluginType)
- ? null
- : GetInstance(pluginType);
+ return !_pipelineGraph.HasDefaultForPluginType(pluginType)
+ ? null
+ : GetInstance(pluginType);
}
/// <summary>
@@ -265,7 +239,7 @@
/// <returns></returns>
public T TryGetInstance<T>()
{
- return (T)(TryGetInstance(typeof (T)) ?? default(T));
+ return (T) (TryGetInstance(typeof (T)) ?? default(T));
}
/// <summary>
@@ -276,11 +250,11 @@
/// <param name="target"></param>
public void BuildUp(object target)
{
- var pluggedType = target.GetType();
- IConfiguredInstance instance = _pipelineGraph.GetDefault(pluggedType) as IConfiguredInstance
- ?? new ConfiguredInstance(pluggedType);
+ Type pluggedType = target.GetType();
+ IConfiguredInstance instance = _pipelineGraph.GetDefault(pluggedType) as IConfiguredInstance
+ ?? new ConfiguredInstance(pluggedType);
- var builder = PluginCache.FindBuilder(pluggedType);
+ InstanceBuilder builder = PluginCache.FindBuilder(pluggedType);
builder.BuildUp(instance, withNewSession(Plugin.DEFAULT), target);
}
@@ -291,7 +265,7 @@
/// <returns></returns>
public T TryGetInstance<T>(string instanceKey)
{
- return (T)(TryGetInstance(typeof(T), instanceKey) ?? default(T));
+ return (T) (TryGetInstance(typeof (T), instanceKey) ?? default(T));
}
/// <summary>
@@ -365,7 +339,7 @@
/// <returns></returns>
public IList GetAllInstances(Type pluginType)
{
- var instances = withNewSession(Plugin.DEFAULT).CreateInstanceArray(pluginType, null);
+ Array instances = withNewSession(Plugin.DEFAULT).CreateInstanceArray(pluginType, null);
return new ArrayList(instances);
}
@@ -434,15 +408,7 @@
return new ExplicitArgsExpression(this).With(argName);
}
- public ExplicitArgsExpression With(Action<ExplicitArgsExpression> action)
- {
- var expression = new ExplicitArgsExpression(this);
- action(expression);
- return expression;
- }
-
-
/// <summary>
/// Use with caution! Does a full environment test of the configuration of this container. Will try to create every configured
/// instance and afterward calls any methods marked with the [ValidationMethod] attribute
@@ -467,8 +433,95 @@
_pipelineGraph.EjectAllInstancesOf<T>();
}
+ /// <summary>
+ /// Convenience method to request an object using an Open Generic
+ /// Type and its parameter Types
+ /// </summary>
+ /// <param name="templateType"></param>
+ /// <returns></returns>
+ /// <example>
+ /// IFlattener flattener1 = container.ForGenericType(typeof (IFlattener<>))
+ /// .WithParameters(typeof (Address)).GetInstanceAs<IFlattener>();
+ /// </example>
+ public OpenGenericTypeExpression ForGenericType(Type templateType)
+ {
+ return new OpenGenericTypeExpression(templateType, this);
+ }
+
+ /// <summary>
+ /// Shortcut syntax for using an object to find a service that handles
+ /// that type of object by using an open generic type
+ /// </summary>
+ /// <example>
+ /// IHandler handler = container.ForObject(shipment)
+ /// .GetClosedTypeOf(typeof (IHandler<>))
+ /// .As<IHandler>();
+ /// </example>
+ /// <param name="subject"></param>
+ /// <returns></returns>
+ public CloseGenericTypeExpression ForObject(object subject)
+ {
+ return new CloseGenericTypeExpression(subject, this);
+ }
+
+ /// <summary>
+ /// Starts a "Nested" Container for atomic, isolated access
+ /// </summary>
+ /// <returns></returns>
+ public IContainer GetNestedContainer()
+ {
+ return new Container()
+ {
+ _interceptorLibrary = _interceptorLibrary,
+ _pipelineGraph = _pipelineGraph.Clone(),
+ _transientCache = new MainObjectCache()
+ };
+ }
+
+ /// <summary>
+ /// Starts a new "Nested" Container for atomic, isolated service location. Opens
+ /// </summary>
+ /// <param name="profileName"></param>
+ /// <returns></returns>
+ public IContainer GetNestedContainer(string profileName)
+ {
+ var container = GetNestedContainer();
+ container.SetDefaultsToProfile(profileName);
+
+ return container;
+ }
+
#endregion
+ private object buildInstanceWithArgs(Type pluginType, Instance defaultInstance, ExplicitArguments args,
+ string requestedName)
+ {
+ if (defaultInstance == null && pluginType.IsConcrete())
+ {
+ defaultInstance = new ConfiguredInstance(pluginType);
+ }
+
+ var basicInstance = defaultInstance as BasicInstance;
+
+ Instance instance = basicInstance == null
+ ? defaultInstance
+ : new ExplicitInstance(pluginType, args, basicInstance);
+
+ BuildSession session = withNewSession(requestedName);
+
+ args.RegisterDefaults(session);
+
+ return session.CreateInstance(pluginType, instance);
+ }
+
+ public ExplicitArgsExpression With(Action<ExplicitArgsExpression> action)
+ {
+ var expression = new ExplicitArgsExpression(this);
+ action(expression);
+
+ return expression;
+ }
+
private void construct(PluginGraph pluginGraph)
{
_interceptorLibrary = pluginGraph.InterceptorLibrary;
@@ -482,7 +535,6 @@
pluginGraph.Log.AssertFailures();
_pipelineGraph = new PipelineGraph(pluginGraph);
- _model = new Model(_pipelineGraph);
PluginCache.Compile();
@@ -492,7 +544,7 @@
private IList<T> getListOfTypeWithSession<T>(BuildSession session)
{
var list = new List<T>();
- foreach (T instance in session.CreateInstanceArray(typeof(T), null))
+ foreach (T instance in session.CreateInstanceArray(typeof (T), null))
{
list.Add(instance);
}
@@ -512,30 +564,27 @@
private BuildSession withNewSession(string name)
{
- return new BuildSession(_pipelineGraph, _interceptorLibrary){RequestedName = name};
+ return new BuildSession(_pipelineGraph, _interceptorLibrary, _transientCache)
+ {
+ RequestedName = name
+ };
}
- /// <summary>
- /// Convenience method to request an object using an Open Generic
- /// Type and its parameter Types
- /// </summary>
- /// <param name="templateType"></param>
- /// <returns></returns>
- /// <example>
- /// IFlattener flattener1 = container.ForGenericType(typeof (IFlattener<>))
- /// .WithParameters(typeof (Address)).GetInstanceAs<IFlattener>();
- /// </example>
- public OpenGenericTypeExpression ForGenericType(Type templateType)
+ #region Nested type: GetInstanceAsExpression
+
+ public interface GetInstanceAsExpression
{
- return new OpenGenericTypeExpression(templateType, this);
+ T GetInstanceAs<T>();
}
-
+ #endregion
+ #region Nested type: OpenGenericTypeExpression
+
public class OpenGenericTypeExpression : GetInstanceAsExpression
{
+ private readonly Container _container;
private readonly Type _templateType;
- private readonly Container _container;
private Type _pluginType;
public OpenGenericTypeExpression(Type templateType, Container container)
@@ -549,39 +598,22 @@
_container = container;
}
- public GetInstanceAsExpression WithParameters(params Type[] parameterTypes)
- {
- _pluginType = _templateType.MakeGenericType(parameterTypes);
- return this;
- }
+ #region GetInstanceAsExpression Members
public T GetInstanceAs<T>()
{
return (T) _container.GetInstance(_pluginType);
}
- }
- public interface GetInstanceAsExpression
- {
- T GetInstanceAs<T>();
+ #endregion
+
+ public GetInstanceAsExpression WithParameters(params Type[] parameterTypes)
+ {
+ _pluginType = _templateType.MakeGenericType(parameterTypes);
+ return this;
+ }
}
- /// <summary>
- /// Shortcut syntax for using an object to find a service that handles
- /// that type of object by using an open generic type
- /// </summary>
- /// <example>
- /// IHandler handler = container.ForObject(shipment)
- /// .GetClosedTypeOf(typeof (IHandler<>))
- /// .As<IHandler>();
- /// </example>
- /// <param name="subject"></param>
- /// <returns></returns>
- public CloseGenericTypeExpression ForObject(object subject)
- {
- return new CloseGenericTypeExpression(subject, this);
- }
+ #endregion
}
-
-
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs
===================================================================
--- trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -17,7 +17,7 @@
private List<IInstance> _explicitInstances;
public ValidationBuildSession(PipelineGraph pipelineGraph, InterceptorLibrary interceptorLibrary)
- : base(pipelineGraph, interceptorLibrary)
+ : base(pipelineGraph, interceptorLibrary, new NulloObjectCache())
{
}
@@ -47,6 +47,7 @@
try
{
+ //clearBuildStack();
return base.CreateInstance(pluginType, instance);
}
catch (StructureMapException ex)
Modified: trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs
===================================================================
--- trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -7,13 +7,18 @@
{
public class GenericsPluginGraph
{
- private readonly Cache<Type, PluginFamily> _families;
+ private Cache<Type, PluginFamily> _families;
public GenericsPluginGraph()
{
_families = new Cache<Type, PluginFamily>(pluginType => new PluginFamily(pluginType));
}
+ public GenericsPluginGraph Clone()
+ {
+ return new GenericsPluginGraph(){_families = _families.Clone()};
+ }
+
public int FamilyCount
{
get { return _families.Count; }
Modified: trunk/Source/StructureMap/IContainer.cs
===================================================================
--- trunk/Source/StructureMap/IContainer.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/IContainer.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -268,5 +268,23 @@
/// <param name="subject"></param>
/// <returns></returns>
CloseGenericTypeExpression ForObject(object subject);
+
+
+
+ /// <summary>
+ /// Starts a "Nested" Container for atomic, isolated access
+ /// </summary>
+ /// <returns></returns>
+ IContainer GetNestedContainer();
+
+ /// <summary>
+ /// Starts a new "Nested" Container for atomic, isolated service location. Opens
+ /// </summary>
+ /// <param name="profileName"></param>
+ /// <returns></returns>
+ IContainer GetNestedContainer(string profileName);
}
+
+
+
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/IInstanceFactory.cs
===================================================================
--- trunk/Source/StructureMap/IInstanceFactory.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/IInstanceFactory.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -12,19 +12,19 @@
public interface IInstanceFactory
{
Type PluginType { get; }
- IEnumerable<IInstance> Instances { get; }
- Instance MissingInstance { get; set; }
+ Instance MissingInstance { get; }
+
Instance[] AllInstances
{
get;
}
+ // need to override this
void AddInstance(Instance instance);
- Instance AddType<T>();
+
Instance FindInstance(string name);
-
void ImportFrom(PluginFamily family);
[Obsolete("Kill!!!!")]
@@ -32,6 +32,7 @@
ILifecycle Lifecycle {get; }
+ IInstanceFactory Clone();
+ }
- }
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/InstanceCache.cs
===================================================================
--- trunk/Source/StructureMap/InstanceCache.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/InstanceCache.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -25,6 +25,16 @@
public object Get(Type pluginType, Instance instance)
{
+ if (pluginType == null)
+ {
+ throw new ArgumentNullException("pluginType");
+ }
+
+ if (instance == null)
+ {
+ throw new ArgumentNullException("instance", "Trying to find an Instance of type " + pluginType.AssemblyQualifiedName);
+ }
+
Dictionary<Instance, object> cache = getCache(pluginType);
if (cache.ContainsKey(instance))
{
Modified: trunk/Source/StructureMap/InstanceFactory.cs
===================================================================
--- trunk/Source/StructureMap/InstanceFactory.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/InstanceFactory.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -12,7 +12,7 @@
/// </summary>
public class InstanceFactory : IInstanceFactory
{
- private readonly Cache<string, Instance> _instances =
+ private Cache<string, Instance> _instances =
new Cache<string, Instance>(delegate { return null; });
private readonly Type _pluginType;
@@ -82,11 +82,6 @@
get { return _pluginType; }
}
- public IEnumerable<IInstance> Instances
- {
- get { return _instances.GetAll(); }
- }
-
public Instance[] AllInstances
{
get
@@ -102,17 +97,6 @@
}
- [Obsolete]
- public Instance AddType<T>()
- {
- ConfiguredInstance instance =
- new ConfiguredInstance(typeof (T)).WithName(TypePath.GetAssemblyQualifiedName(typeof (T)));
-
- AddInstance(instance);
-
- return instance;
- }
-
public Instance FindInstance(string name)
{
return _instances[name] ?? MissingInstance;
@@ -149,7 +133,18 @@
get { return _lifecycle; }
set { _lifecycle = value; }
}
+
+ public IInstanceFactory Clone()
+ {
+ var factory = new InstanceFactory(_pluginType);
+ factory.MissingInstance = MissingInstance;
+ factory._lifecycle = _lifecycle;
+ factory._instances = _instances.Clone();
+
+ return factory;
+ }
+
#endregion
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Pipeline/BuildStack.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/BuildStack.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Pipeline/BuildStack.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -64,5 +64,10 @@
_current = _current.Detach();
if (_current == null) _root = null;
}
+
+ public void Clear()
+ {
+ _current = _root = null;
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Pipeline/ConfiguredInstanceBase.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/ConfiguredInstanceBase.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Pipeline/ConfiguredInstanceBase.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -206,6 +206,15 @@
protected void setChildArray(string name, Instance[] array)
{
+ for (int i = 0; i < array.Length; i++)
+ {
+ if (array[i] == null)
+ {
+ throw new ApplicationException("There is a null value in the array of child Instances");
+ }
+
+ }
+
_arrays.Add(name, array);
}
Added: trunk/Source/StructureMap/Pipeline/ILifecycle.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/ILifecycle.cs (rev 0)
+++ trunk/Source/StructureMap/Pipeline/ILifecycle.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -0,0 +1,8 @@
+namespace StructureMap.Pipeline
+{
+ public interface ILifecycle
+ {
+ void EjectAll();
+ IObjectCache FindCache();
+ }
+}
\ No newline at end of file
Added: trunk/Source/StructureMap/Pipeline/IObjectCache.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/IObjectCache.cs (rev 0)
+++ trunk/Source/StructureMap/Pipeline/IObjectCache.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -0,0 +1,18 @@
+using System;
+
+namespace StructureMap.Pipeline
+{
+ public interface IObjectCache
+ {
+ object Locker { get; }
+
+ int Count
+ {
+ get;
+ }
+
+ object Get(Type pluginType, Instance instance);
+ void Set(Type pluginType, Instance instance, object value);
+ void DisposeAndClear();
+ }
+}
\ No newline at end of file
Added: trunk/Source/StructureMap/Pipeline/Lifecycles.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/Lifecycles.cs (rev 0)
+++ trunk/Source/StructureMap/Pipeline/Lifecycles.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -0,0 +1,37 @@
+using System;
+using StructureMap.Attributes;
+
+namespace StructureMap.Pipeline
+{
+ public static class Lifecycles
+ {
+ public static ILifecycle GetLifecycle(InstanceScope scope)
+ {
+ switch (scope)
+ {
+ case InstanceScope.PerRequest:
+ return null;
+
+ case InstanceScope.Singleton:
+ return new SingletonLifecycle();
+
+ case InstanceScope.HttpContext:
+ return new HttpContextLifecycle();
+
+ case InstanceScope.ThreadLocal:
+ return new ThreadLocalStorageLifecycle();
+
+ case InstanceScope.Hybrid:
+ return new HybridLifecycle();
+
+ case InstanceScope.HttpSession:
+ return new HttpSessionLifecycle();
+
+ case InstanceScope.HybridHttpSession:
+ return new HybridSessionLifecycle();
+ }
+
+ throw new ArgumentOutOfRangeException("scope");
+ }
+ }
+}
\ No newline at end of file
Added: trunk/Source/StructureMap/Pipeline/MainObjectCache.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/MainObjectCache.cs (rev 0)
+++ trunk/Source/StructureMap/Pipeline/MainObjectCache.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+
+namespace StructureMap.Pipeline
+{
+ public class MainObjectCache : IObjectCache
+ {
+ private readonly IDictionary<InstanceKey, object> _objects = new Dictionary<InstanceKey,object>();
+ private readonly object _locker = new object();
+
+ public object Locker
+ {
+ get { return _locker; }
+ }
+
+ public int Count
+ {
+ get { return _objects.Count; }
+ }
+
+ public object Get(Type pluginType, Instance instance)
+ {
+ var key = new InstanceKey(instance, pluginType);
+ return _objects.ContainsKey(key) ? _objects[key] : null;
+ }
+
+ public void Set(Type pluginType, Instance instance, object value)
+ {
+ var key = new InstanceKey(instance, pluginType);
+ _objects.Add(key, value);
+ }
+
+ public void DisposeAndClear()
+ {
+ lock (Locker)
+ {
+ foreach (var @object in _objects.Values)
+ {
+ IDisposable disposable = @object as IDisposable;
+ if (disposable != null)
+ {
+ try
+ {
+ disposable.Dispose();
+ }
+ catch (Exception) { }
+ }
+ }
+
+ _objects.Clear();
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/Source/StructureMap/Pipeline/NulloObjectCache.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/NulloObjectCache.cs (rev 0)
+++ trunk/Source/StructureMap/Pipeline/NulloObjectCache.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -0,0 +1,32 @@
+using System;
+
+namespace StructureMap.Pipeline
+{
+ public class NulloObjectCache : IObjectCache
+ {
+ public object Locker
+ {
+ get { return new object(); }
+ }
+
+ public int Count
+ {
+ get { return 0; }
+ }
+
+ public object Get(Type pluginType, Instance instance)
+ {
+ return null;
+ }
+
+ public void Set(Type pluginType, Instance instance, object value)
+ {
+ // no-op
+ }
+
+ public void DisposeAndClear()
+ {
+ // no-op
+ }
+ }
+}
\ No newline at end of file
Added: trunk/Source/StructureMap/Pipeline/ObjectBuilder.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/ObjectBuilder.cs (rev 0)
+++ trunk/Source/StructureMap/Pipeline/ObjectBuilder.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -0,0 +1,69 @@
+using System;
+using StructureMap.Interceptors;
+
+namespace StructureMap.Pipeline
+{
+ public class ObjectBuilder
+ {
+ private readonly PipelineGraph _pipeline;
+ private readonly InterceptorLibrary _library;
+ private readonly IObjectCache _defaultCache;
+
+ public ObjectBuilder(PipelineGraph pipeline, InterceptorLibrary library, IObjectCache defaultCache)
+ {
+ if (pipeline == null) throw new ArgumentNullException("pipeline");
+
+ _pipeline = pipeline;
+ _library = library;
+ _defaultCache = defaultCache;
+ }
+
+ public object Resolve(Type pluginType, Instance instance, BuildSession session)
+ {
+ var cache = FindCache(pluginType, instance, session);
+ lock (cache.Locker)
+ {
+ var returnValue = cache.Get(pluginType, instance);
+ if (returnValue == null)
+ {
+ returnValue = ConstructNew(pluginType, instance, session);
+
+
+ cache.Set(pluginType, instance, returnValue);
+ }
+
+ return returnValue;
+ }
+ }
+
+ public object ConstructNew(Type pluginType, Instance instance, BuildSession session)
+ {
+ object returnValue = instance.Build(pluginType, session);
+ return ApplyInterception(pluginType, returnValue, session, instance);
+ }
+
+ public virtual object ApplyInterception(Type pluginType, object actualValue, BuildSession session, Instance instance)
+ {
+ if (actualValue == null) return null;
+
+ try
+ {
+ return _library.FindInterceptor(actualValue.GetType()).Process(actualValue, session);
+ }
+ catch (Exception e)
+ {
+ throw new StructureMapException(308, e, instance.Name, actualValue.GetType());
+ }
+
+
+ }
+
+ public IObjectCache FindCache(Type pluginType, Instance instance, BuildSession session)
+ {
+ var lifecycle = _pipeline.ForType(pluginType).Lifecycle;
+ return lifecycle == null
+ ? _defaultCache
+ : lifecycle.FindCache();
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Pipeline/ProfileManager.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/ProfileManager.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Pipeline/ProfileManager.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -224,6 +224,19 @@
CurrentProfile = CurrentProfile;
}
+ public ProfileManager Clone()
+ {
+ var clone = new ProfileManager()
+ {
+ DefaultMachineProfileName = DefaultMachineProfileName,
+ DefaultProfileName = DefaultProfileName
+ };
+
+ clone.ImportFrom(this);
+
+ return clone;
+ }
+
public void EjectAllInstancesOf<T>()
{
_currentProfile.Remove<T>();
Modified: trunk/Source/StructureMap/PipelineGraph.cs
===================================================================
--- trunk/Source/StructureMap/PipelineGraph.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/PipelineGraph.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -41,6 +41,27 @@
}
}
+ private PipelineGraph(ProfileManager profileManager, GenericsPluginGraph genericsGraph)
+ {
+ _profileManager = profileManager;
+ _genericsGraph = genericsGraph;
+ }
+
+ public PipelineGraph Clone()
+ {
+ var clone = new PipelineGraph(_profileManager.Clone(), _genericsGraph.Clone())
+ {
+ _missingFactory = _missingFactory
+ };
+
+ foreach (var pair in _factories)
+ {
+ clone._factories.Add(pair.Key, pair.Value);
+ }
+
+ return clone;
+ }
+
public GraphLog Log
{
get { return _log; }
@@ -76,7 +97,7 @@
Default = _profileManager.GetDefault(factory.PluginType),
PluginType = factory.PluginType,
Lifecycle = factory.Lifecycle,
- Instances = factory.Instances
+ Instances = factory.AllInstances
};
}
}
@@ -152,22 +173,12 @@
_profileManager.SetDefault(pluginType, instance);
}
- public Instance AddInstance<PLUGINTYPE, PLUGGEDTYPE>()
- {
- return ForType(typeof (PLUGINTYPE)).AddType<PLUGGEDTYPE>();
- }
public void AddInstance<T>(Instance instance)
{
ForType(typeof (T)).AddInstance(instance);
}
- public void AddDefaultInstance<PLUGINTYPE, PLUGGEDTYPE>()
- {
- Instance instance = AddInstance<PLUGINTYPE, PLUGGEDTYPE>();
- _profileManager.SetDefault(typeof (PLUGINTYPE), instance);
- }
-
public void Inject<PLUGINTYPE>(PLUGINTYPE instance)
{
var literalInstance = new LiteralInstance(instance);
@@ -190,7 +201,7 @@
if (_factories.ContainsKey(pluginType))
{
- return _factories[pluginType].Instances;
+ return _factories[pluginType].AllInstances;
}
return new IInstance[0];
@@ -202,7 +213,7 @@
foreach (var pair in _factories)
{
- list.AddRange(pair.Value.Instances);
+ list.AddRange(pair.Value.AllInstances);
}
return list;
Modified: trunk/Source/StructureMap/StructureMap.csproj
===================================================================
--- trunk/Source/StructureMap/StructureMap.csproj 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/StructureMap.csproj 2009-06-03 16:21:03 UTC (rev 247)
@@ -404,7 +404,12 @@
<Compile Include="Pipeline\HttpLifecycleBase.cs" />
<Compile Include="Pipeline\HttpSessionLifecycle.cs" />
<Compile Include="Pipeline\HybridSessionLifecycle.cs" />
- <Compile Include="Pipeline\Lifecycle.cs" />
+ <Compile Include="Pipeline\ILifecycle.cs" />
+ <Compile Include="Pipeline\IObjectCache.cs" />
+ <Compile Include="Pipeline\Lifecycles.cs" />
+ <Compile Include="Pipeline\MainObjectCache.cs" />
+ <Compile Include="Pipeline\NulloObjectCache.cs" />
+ <Compile Include="Pipeline\ObjectBuilder.cs" />
<Compile Include="Pipeline\SessionWrapper.cs" />
<Compile Include="Pipeline\SingletonLifecycle.cs" />
<Compile Include="Pipeline\ThreadLocalStorageLifecycle.cs" />
Modified: trunk/Source/StructureMap/Util/Cache.cs
===================================================================
--- trunk/Source/StructureMap/Util/Cache.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap/Util/Cache.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -9,8 +9,6 @@
private readonly object _locker = new object();
private readonly IDictionary<KEY, VALUE> _values;
- private Func<VALUE, KEY> _getKey = delegate { throw new NotImplementedException(); };
-
private Func<KEY, VALUE> _onMissing = delegate(KEY key)
{
string message = string.Format("Key '{0}' could not be found", key);
@@ -38,22 +36,11 @@
_values = dictionary;
}
- public object Locker
- {
- get { return _locker; }
- }
-
public Func<KEY, VALUE> OnMissing
{
set { _onMissing = value; }
}
- public Func<VALUE, KEY> GetKey
- {
- get { return _getKey; }
- set { _getKey = value; }
- }
-
public int Count
{
get { return _values.Count; }
@@ -135,19 +122,6 @@
_values.Add(key, value);
}
- public bool TryRetrieve(KEY key, out VALUE value)
- {
- value = default(VALUE);
-
- if (_values.ContainsKey(key))
- {
- value = _values[key];
- return true;
- }
-
- return false;
- }
-
public void Each(Action<VALUE> action)
{
lock (_locker)
@@ -214,5 +188,13 @@
{
_values.Clear();
}
+
+ public Cache<KEY, VALUE> Clone()
+ {
+ var clone = new Cache<KEY, VALUE>(_onMissing);
+ Each((k, v) => clone[k] = v);
+
+ return clone;
+ }
}
}
Modified: trunk/Source/StructureMap.Testing/BuildSessionTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/BuildSessionTester.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap.Testing/BuildSessionTester.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -151,7 +151,7 @@
assertActionThrowsErrorCode(200, delegate
{
- var session = new BuildSession(graph, null);
+ var session = new BuildSession(graph, null, new NulloObjectCache());
session.CreateInstance(typeof (IGateway), "Gateway that is not configured");
});
}
@@ -183,7 +183,7 @@
assertActionThrowsErrorCode(202, delegate
{
- var session = new BuildSession(graph, null);
+ var session = new BuildSession(graph, null, new NulloObjectCache());
session.CreateInstance(typeof (IGateway));
});
}
Modified: trunk/Source/StructureMap.Testing/Graph/InstanceFactoryTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Graph/InstanceFactoryTester.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap.Testing/Graph/InstanceFactoryTester.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -71,7 +71,7 @@
factory.EjectAllInstances();
- factory.Instances.Count().ShouldEqual(0);
+ factory.AllInstances.Count().ShouldEqual(0);
lifecycle.AssertWasCalled(x => x.EjectAll());
}
@@ -143,4 +143,58 @@
}
+
+ [TestFixture]
+ public class when_cloning_an_InstanceFactory
+ {
+ private InstanceFactory factory;
+ private IInstanceFactory clone;
+
+ [SetUp]
+ public void SetUp()
+ {
+ factory = new InstanceFactory(typeof(IGateway));
+ factory.AddInstance(new SmartInstance<DefaultGateway>());
+ factory.AddInstance(new SmartInstance<DefaultGateway>());
+
+ var lifecycle = MockRepository.GenerateMock<ILifecycle>();
+ factory.Lifecycle = lifecycle;
+ factory.MissingInstance = new SmartInstance<DefaultGateway>();
+
+ clone = factory.Clone();
+ }
+
+ [Test]
+ public void missing_instance_is_copied()
+ {
+ clone.MissingInstance.ShouldBeTheSameAs(factory.MissingInstance);
+ }
+
+ [Test]
+ public void lifecycle_is_copied()
+ {
+ clone.Lifecycle.ShouldBeTheSameAs(factory.Lifecycle);
+ }
+
+ [Test]
+ public void plugin_type_is_set_on_the_clone()
+ {
+ clone.PluginType.ShouldEqual(typeof (IGateway));
+ }
+
+ [Test]
+ public void the_instances_are_copied()
+ {
+ clone.AllInstances.Count().ShouldEqual(2);
+ }
+
+ [Test]
+ public void the_instances_are_cloned_so_that_new_instances_are_NOT_injected_into_()
+ {
+ clone.AddInstance(new LiteralInstance(new DefaultGateway()));
+
+ factory.AllInstances.Count().ShouldEqual(2);
+ clone.AllInstances.Count().ShouldEqual(3);
+ }
+ }
}
\ No newline at end of file
Modified: trunk/Source/StructureMap.Testing/Pipeline/ConfiguredInstanceTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Pipeline/ConfiguredInstanceTester.cs 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap.Testing/Pipeline/ConfiguredInstanceTester.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -30,7 +30,7 @@
PluginGraph graph = registry.Build();
var pipelineGraph = new PipelineGraph(graph);
- _session = new BuildSession(pipelineGraph, graph.InterceptorLibrary);
+ _session = new BuildSession(pipelineGraph, graph.InterceptorLibrary, new NulloObjectCache());
}
#endregion
Added: trunk/Source/StructureMap.Testing/Pipeline/NestedContainerSupportTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Pipeline/NestedContainerSupportTester.cs (rev 0)
+++ trunk/Source/StructureMap.Testing/Pipeline/NestedContainerSupportTester.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -0,0 +1,131 @@
+using NUnit.Framework;
+using StructureMap.Attributes;
+using StructureMap.Configuration.DSL;
+using StructureMap.Testing.GenericWidgets;
+using StructureMap.Testing.Widget;
+
+namespace StructureMap.Testing.Pipeline
+{
+ [TestFixture]
+ public class NestedContainerSupportTester
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ }
+
+ [Test]
+ public void transient_service_in_the_parent_container_is_effectively_a_singleton_for_the_nested_container()
+ {
+ var parent = new Container(x =>
+ {
+ x.For<IWidget>().Use<AWidget>();
+ });
+
+ var child = parent.GetNestedContainer();
+
+ var childWidget1 = child.GetInstance<IWidget>();
+ var childWidget2 = child.GetInstance<IWidget>();
+ var childWidget3 = child.GetInstance<IWidget>();
+
+ var parentWidget = parent.GetInstance<IWidget>();
+
+ childWidget1.ShouldBeTheSameAs(childWidget2);
+ childWidget1.ShouldBeTheSameAs(childWidget3);
+ childWidget1.ShouldNotBeTheSameAs(parentWidget);
+ }
+
+ [Test]
+ public void singleton_service_in_the_parent_is_found_by_the_child()
+ {
+ var parent = new Container(x =>
+ {
+ x.ForSingletonOf<IWidget>().Use<AWidget>();
+ });
+
+ var parentWidget = parent.GetInstance<IWidget>();
+
+ var child = parent.GetNestedContainer();
+
+ var childWidget1 = child.GetInstance<IWidget>();
+ var childWidget2 = child.GetInstance<IWidget>();
+
+ parentWidget.ShouldBeTheSameAs(childWidget1);
+ parentWidget.ShouldBeTheSameAs(childWidget2);
+ }
+
+ [Test]
+ public void transient_open_generics_service_in_the_parent_container_is_effectively_a_singleton_for_the_nested_container()
+ {
+ var parent = new Container(x =>
+ {
+ x.For(typeof(IService<>)).Use(typeof(Service<>));
+ });
+
+ var child = parent.GetNestedContainer();
+
+ var childWidget1 = child.GetInstance<IService<string>>();
+ var childWidget2 = child.GetInstance<IService<string>>();
+ var childWidget3 = child.GetInstance<IService<string>>();
+
+ var parentWidget = parent.GetInstance<IService<string>>();
+
+ childWidget1.ShouldBeTheSameAs(childWidget2);
+ childWidget1.ShouldBeTheSameAs(childWidget3);
+ childWidget1.ShouldNotBeTheSameAs(parentWidget);
+ }
+
+ [Test]
+ public void singleton_service_from_open_type_in_the_parent_is_found_by_the_child()
+ {
+ var parent = new Container(x =>
+ {
+ x.For(typeof(IService<>)).CacheBy(InstanceScope.Singleton).Use(typeof(Service<>));
+ });
+
+ var child = parent.GetNestedContainer();
+
+ var childWidget1 = child.GetInstance<IService<string>>();
+ var childWidget2 = child.GetInstance<IService<string>>();
+ var childWidget3 = child.GetInstance<IService<string>>();
+
+ var parentWidget = parent.GetInstance<IService<string>>();
+
+ childWidget1.ShouldBeTheSameAs(childWidget2);
+ childWidget1.ShouldBeTheSameAs(childWidget3);
+ childWidget1.ShouldBeTheSameAs(parentWidget);
+ }
+
+ [Test]
+ public void get_a_nested_container_for_a_profile()
+ {
+ var parent = new Container(x =>
+ {
+ x.For<IWidget>().TheDefault.Is.OfConcreteType<ColorWidget>()
+ .WithCtorArg("color").EqualTo("red");
+
+ x.CreateProfile("green", o =>
+ {
+ o.Type<IWidget>().Is.OfConcreteType<ColorWidget>()
+ .WithCtorArg("color").EqualTo("green");
+ });
+
+ });
+
+ var child = parent.GetNestedContainer("green");
+
+ var childWidget1 = child.GetInstance<IWidget>();
+ var childWidget2 = child.GetInstance<IWidget>();
+ var childWidget3 = child.GetInstance<IWidget>();
+
+ var parentWidget = parent.GetInstance<IWidget>();
+
+ childWidget1.ShouldBeTheSameAs(childWidget2);
+ childWidget1.ShouldBeTheSameAs(childWidget3);
+ childWidget1.ShouldNotBeTheSameAs(parentWidget);
+
+ parentWidget.ShouldBeOfType<ColorWidget>().Color.ShouldEqual("red");
+ childWidget1.ShouldBeOfType<ColorWidget>().Color.ShouldEqual("green");
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj
===================================================================
--- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2009-06-03 16:21:03 UTC (rev 247)
@@ -353,6 +353,7 @@
<Compile Include="Pipeline\InstanceTester.cs" />
<Compile Include="Pipeline\LiteralInstanceTester.cs" />
<Compile Include="Pipeline\MissingInstanceTester.cs" />
+ <Compile Include="Pipeline\NestedContainerSupportTester.cs" />
<Compile Include="Pipeline\ObjectBuilderTester.cs" />
<Compile Include="Pipeline\OptionalSetterInjectionTester.cs" />
<Compile Include="Pipeline\ProfileManagerMergeTester.cs" />
@@ -383,6 +384,7 @@
<Compile Include="TestUtility.cs" />
<Compile Include="Diagnostics\ValidationBuildSessionTester.cs" />
<Compile Include="TypeExtensionsTester.cs" />
+ <Compile Include="Util\CacheTester.cs" />
<Compile Include="XmlWriting\ElementChecker.cs">
<SubType>Code</SubType>
</Compile>
Added: trunk/Source/StructureMap.Testing/Util/CacheTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Util/CacheTester.cs (rev 0)
+++ trunk/Source/StructureMap.Testing/Util/CacheTester.cs 2009-06-03 16:21:03 UTC (rev 247)
@@ -0,0 +1,35 @@
+using NUnit.Framework;
+using StructureMap.Testing.Widget;
+using StructureMap.Util;
+
+namespace StructureMap.Testing.Util
+{
+ [TestFixture]
+ public class CacheTester
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ }
+
+ [Test]
+ public void cloning_test()
+ {
+ var cache = new Cache<string, IWidget>(x => new ColorWidget(x));
+
+ var red = cache["red"];
+ var blue = cache["blue"];
+ var green = cache["green"];
+
+ var clone = cache.Clone();
+
+ clone["red"].ShouldBeTheSameAs(red);
+ clone["blue"].ShouldBeTheSameAs(blue);
+ clone["green"].ShouldBeTheSameAs(green);
+
+ clone["purple"].ShouldBeOfType<ColorWidget>().Color.ShouldEqual("purple");
+
+ clone["purple"].ShouldNotBeTheSameAs(cache["purple"]);
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap.sln
===================================================================
--- trunk/Source/StructureMap.sln 2009-06-03 03:04:58 UTC (rev 246)
+++ trunk/Source/StructureMap.sln 2009-06-03 16:21:03 UTC (rev 247)
@@ -4,7 +4,6 @@
ProjectSection(SolutionItems) = preProject
..\Docs\Attributes.htm = ..\Docs\Attributes.htm
..\Docs\Basic Architecture.htm = ..\Docs\Basic Architecture.htm
- CommonAssemblyInfo.cs = CommonAssemblyInfo.cs
..\Docs\Concepts.htm = ..\Docs\Concepts.htm
..\Docs\Configuration.htm = ..\Docs\Configuration.htm
..\Docs\ConfigurationManagement.htm = ..\Docs\ConfigurationManagement.htm
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|