|
From: <jer...@us...> - 2009-12-28 04:07:29
|
Revision: 309
http://structuremap.svn.sourceforge.net/structuremap/?rev=309&view=rev
Author: jeremydmiller
Date: 2009-12-28 04:07:20 +0000 (Mon, 28 Dec 2009)
Log Message:
-----------
Finished the work on the new "Model" subsystem
Modified Paths:
--------------
trunk/Source/StructureMap/Container.cs
trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs
trunk/Source/StructureMap/Graph/PluginFamily.cs
trunk/Source/StructureMap/Pipeline/Profile.cs
trunk/Source/StructureMap/Pipeline/ProfileManager.cs
trunk/Source/StructureMap/PipelineGraph.cs
trunk/Source/StructureMap/Query/EmptyConfiguration.cs
trunk/Source/StructureMap/Query/GenericFamilyConfiguration.cs
trunk/Source/StructureMap/Query/IModel.cs
trunk/Source/StructureMap/Query/IPluginTypeConfiguration.cs
trunk/Source/StructureMap/Query/InstanceFactoryTypeConfiguration.cs
trunk/Source/StructureMap/Query/Model.cs
trunk/Source/StructureMap/TypeExtensions.cs
trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs
trunk/Source/StructureMap.Testing/Query/ModelIntegrationTester.cs
Modified: trunk/Source/StructureMap/Container.cs
===================================================================
--- trunk/Source/StructureMap/Container.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Container.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -64,7 +64,13 @@
/// <summary>
/// Provides queryable access to the configured PluginType's and Instances of this Container
/// </summary>
- public IModel Model { get { return new Model(_pipelineGraph.GetPluginTypes(this)); } }
+ public IModel Model
+ {
+ get
+ {
+ return new Model(_pipelineGraph, this);
+ }
+ }
/// <summary>
/// Creates or finds the named instance of T
Modified: trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs
===================================================================
--- trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -160,5 +160,10 @@
{
_families.Clear();
}
+
+ public void Remove(Type pluginType)
+ {
+ _families.Remove(pluginType);
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Graph/PluginFamily.cs
===================================================================
--- trunk/Source/StructureMap/Graph/PluginFamily.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Graph/PluginFamily.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -361,5 +361,12 @@
}
}
+
+ public void RemoveAll()
+ {
+ _instances.Clear();
+ _mementoList.Clear();
+ _defaultKey = null;
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Pipeline/Profile.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/Profile.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Pipeline/Profile.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -105,9 +105,9 @@
}
- public void Remove<T>()
+ public void Remove(Type pluginType)
{
- _instances.Remove(typeof (T));
+ _instances.Remove(pluginType);
}
public void Clear()
Modified: trunk/Source/StructureMap/Pipeline/ProfileManager.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/ProfileManager.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Pipeline/ProfileManager.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -216,13 +216,9 @@
return clone;
}
- public void EjectAllInstancesOf<T>()
+ public void EjectAllInstancesOf(Type pluginType)
{
- _currentProfile.Remove<T>();
- foreach (var pair in _profiles)
- {
- pair.Value.Remove<T>();
- }
+ profiles.Each(x => x.Remove(pluginType));
}
public void RemoveInstance(Type pluginType, Instance instance)
Modified: trunk/Source/StructureMap/PipelineGraph.cs
===================================================================
--- trunk/Source/StructureMap/PipelineGraph.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/PipelineGraph.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -188,11 +188,29 @@
public void EjectAllInstancesOf<T>()
{
- ForType(typeof (T)).EjectAllInstances();
- _profileManager.EjectAllInstancesOf<T>();
+ EjectAllInstancesOf(typeof(T));
}
+ public void EjectAllInstancesOf(Type pluginType)
+ {
+ ForType(pluginType).EjectAllInstances();
+ _profileManager.EjectAllInstancesOf(pluginType);
+ }
+ public void Remove(Func<Type, bool> filter)
+ {
+ _genericsGraph.Families.Where(x => filter(x.PluginType)).ToArray().Each(x => Remove(x.PluginType));
+ _factories.Values.Where(x => filter(x.PluginType)).ToArray().Each(x => Remove(x.PluginType));
+ }
+
+ public void Remove(Type pluginType)
+ {
+ EjectAllInstancesOf(pluginType);
+ _factories.Remove(pluginType);
+ _genericsGraph.Remove(pluginType);
+ }
+
+
public List<Instance> GetAllInstances()
{
return _factories.Values.SelectMany(x => x.AllInstances).ToList();
@@ -232,5 +250,8 @@
ForType(pluginType).RemoveInstance(instance);
_profileManager.RemoveInstance(pluginType, instance);
}
+
+
+
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Query/EmptyConfiguration.cs
===================================================================
--- trunk/Source/StructureMap/Query/EmptyConfiguration.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Query/EmptyConfiguration.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -44,5 +44,8 @@
{
}
+ public void EjectAndRemoveAll()
+ {
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Query/GenericFamilyConfiguration.cs
===================================================================
--- trunk/Source/StructureMap/Query/GenericFamilyConfiguration.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Query/GenericFamilyConfiguration.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -70,6 +70,9 @@
_family.RemoveInstance(instance.Instance);
}
-
+ public void EjectAndRemoveAll()
+ {
+ _family.RemoveAll();
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Query/IModel.cs
===================================================================
--- trunk/Source/StructureMap/Query/IModel.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Query/IModel.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -90,5 +90,32 @@
/// <param name="type"></param>
/// <returns></returns>
IPluginTypeConfiguration For(Type type);
+
+ /// <summary>
+ /// Eject all objects, configuration, and Plugin Types matching this filter
+ /// </summary>
+ /// <param name="filter"></param>
+ void EjectAndRemoveTypes(Func<Type, bool> filter);
+
+ /// <summary>
+ /// Eject all objects and configuration for any Plugin Type that matches this filter
+ /// </summary>
+ /// <param name="filter"></param>
+ void EjectAndRemovePluginTypes(Func<Type, bool> filter);
+
+ /// <summary>
+ /// Eject all objects and Instance configuration for this PluginType
+ /// </summary>
+ /// <param name="pluginType"></param>
+ void EjectAndRemove(Type pluginType);
+
+
+ /// <summary>
+ /// Get each and every configured instance that could possibly
+ /// be cast to T
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ IEnumerable<T> GetAllPossible<T>() where T : class;
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Query/IPluginTypeConfiguration.cs
===================================================================
--- trunk/Source/StructureMap/Query/IPluginTypeConfiguration.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Query/IPluginTypeConfiguration.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -38,6 +38,11 @@
/// <param name="instance"></param>
void EjectAndRemove(InstanceRef instance);
+ /// <summary>
+ /// Eject all instances of this PluginType from the current container,
+ /// but leaves the lifecycle behavior
+ /// </summary>
+ void EjectAndRemoveAll();
}
public static class PluginTypeConfigurationExtensions
Modified: trunk/Source/StructureMap/Query/InstanceFactoryTypeConfiguration.cs
===================================================================
--- trunk/Source/StructureMap/Query/InstanceFactoryTypeConfiguration.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Query/InstanceFactoryTypeConfiguration.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -80,7 +80,12 @@
_graph.Remove(_pluginType, instance.Instance);
}
-
+ public void EjectAndRemoveAll()
+ {
+ _graph.EjectAllInstancesOf(_pluginType);
+ }
+
+
private InstanceRef toRef(Instance instance)
{
if (instance == null) return null;
Modified: trunk/Source/StructureMap/Query/Model.cs
===================================================================
--- trunk/Source/StructureMap/Query/Model.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/Query/Model.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -1,16 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using StructureMap.TypeRules;
namespace StructureMap.Query
{
public class Model : IModel
{
- private readonly IEnumerable<IPluginTypeConfiguration> _pluginTypes;
+ private PipelineGraph _graph;
+ private IContainer _container;
- internal Model(IEnumerable<IPluginTypeConfiguration> pluginTypes)
+ internal Model(PipelineGraph graph, IContainer container)
{
- _pluginTypes = pluginTypes;
+ _graph = graph;
+ _container = container;
}
#region IModel Members
@@ -35,8 +38,16 @@
return findForFamily(pluginType, f => f.Default == null ? null : f.Default.ConcreteType);
}
- public IEnumerable<IPluginTypeConfiguration> PluginTypes { get { return _pluginTypes; } }
+ private IEnumerable<IPluginTypeConfiguration> pluginTypes
+ {
+ get
+ {
+ return _graph.GetPluginTypes(_container);
+ }
+ }
+ public IEnumerable<IPluginTypeConfiguration> PluginTypes { get { return pluginTypes; } }
+
/// <summary>
/// Retrieves the configuration for the given type
/// </summary>
@@ -54,9 +65,58 @@
/// <returns></returns>
public IPluginTypeConfiguration For(Type type)
{
- return _pluginTypes.FirstOrDefault(x => x.PluginType == type) ?? new EmptyConfiguration(type);
+ return pluginTypes.FirstOrDefault(x => x.PluginType == type) ?? new EmptyConfiguration(type);
}
+ /// <summary>
+ /// Eject all objects, configuration, and Plugin Types matching this filter
+ /// </summary>
+ /// <param name="filter"></param>
+ public void EjectAndRemoveTypes(Func<Type, bool> filter)
+ {
+ // first pass hits plugin types
+ EjectAndRemovePluginTypes(filter);
+
+ // second pass to hit instances
+ pluginTypes.Each(x =>
+ {
+ x.EjectAndRemove(i => filter(i.ConcreteType));
+ });
+ }
+
+ /// <summary>
+ /// Eject all objects and configuration for any Plugin Type that matches this filter
+ /// </summary>
+ /// <param name="filter"></param>
+ public void EjectAndRemovePluginTypes(Func<Type, bool> filter)
+ {
+ _graph.Remove(filter);
+ }
+
+ /// <summary>
+ /// Eject all objects and Instance configuration for this PluginType
+ /// </summary>
+ /// <param name="pluginType"></param>
+ public void EjectAndRemove(Type pluginType)
+ {
+ _graph.Remove(pluginType);
+ }
+
+ /// <summary>
+ /// Get each and every configured instance that could possibly
+ /// be cast to T
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public IEnumerable<T> GetAllPossible<T>() where T : class
+ {
+ Type targetType = typeof (T);
+ return AllInstances
+ .Where(x => x.ConcreteType.CanBeCastTo(targetType))
+ .Select(x => x.Get<T>())
+ .Where(x => x != null);
+ }
+
public IEnumerable<InstanceRef> InstancesOf(Type pluginType)
{
return findForFamily(pluginType, x => x.Instances, new InstanceRef[0]);
Modified: trunk/Source/StructureMap/TypeExtensions.cs
===================================================================
--- trunk/Source/StructureMap/TypeExtensions.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap/TypeExtensions.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -173,6 +173,8 @@
/// <returns></returns>
public static bool CanBeCastTo(this Type pluggedType, Type pluginType)
{
+ if (pluggedType == null) return false;
+
if (pluggedType.IsInterface || pluggedType.IsAbstract)
{
return false;
Modified: trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -208,6 +208,24 @@
}
[Test]
+ public void remove_all_clears_the_defaul_and_removes_all_plugins_instances()
+ {
+ var family = new PluginFamily(typeof(IServiceProvider));
+ var instance = new SmartInstance<DataSet>();
+
+ family.SetDefault(instance);
+
+ family.AddInstance(new NullInstance());
+ family.AddType(typeof(DataSet));
+
+ family.RemoveAll();
+
+ family.DefaultInstanceKey.ShouldBeNull();
+
+ family.InstanceCount.ShouldEqual(0);
+ }
+
+ [Test]
public void set_the_scope_to_session()
{
var family = new PluginFamily(typeof (IServiceProvider));
Modified: trunk/Source/StructureMap.Testing/Query/ModelIntegrationTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Query/ModelIntegrationTester.cs 2009-12-28 02:57:22 UTC (rev 308)
+++ trunk/Source/StructureMap.Testing/Query/ModelIntegrationTester.cs 2009-12-28 04:07:20 UTC (rev 309)
@@ -32,6 +32,10 @@
});
x.For<IEngine>().Use<PushrodEngine>();
+
+ x.For<Startable1>().Singleton().Use<Startable1>();
+ x.For<Startable2>().Use<Startable2>();
+ x.For<Startable3>().Use<Startable3>();
});
}
@@ -40,10 +44,63 @@
private Container container;
[Test]
+ public void remove_types_based_on_a_filter()
+ {
+ container.GetAllInstances<Rule>().Any(x => x is ARule).ShouldBeTrue();
+ container.Model.HasImplementationsFor<IWidget>().ShouldBeTrue();
+
+ container.Model.EjectAndRemoveTypes(t => t == typeof(IWidget) || t == typeof(ARule));
+
+ container.GetAllInstances<Rule>().Any(x => x is ARule).ShouldBeFalse();
+ container.Model.HasImplementationsFor<IWidget>().ShouldBeFalse();
+ }
+
+ [Test]
+ public void remove_an_entire_closed_type()
+ {
+ container.Model.EjectAndRemove(typeof(Rule));
+ container.Model.HasImplementationsFor<Rule>().ShouldBeFalse();
+
+ container.TryGetInstance<Rule>().ShouldBeNull();
+ container.GetAllInstances<Rule>().Count.ShouldEqual(0);
+
+ }
+
+ [Test]
+ public void remove_an_entire_closed_type_with_the_filter()
+ {
+ container.Model.EjectAndRemovePluginTypes(t => t == typeof(Rule) || t == typeof(IWidget));
+
+ container.Model.HasImplementationsFor<IWidget>().ShouldBeFalse();
+ container.Model.HasImplementationsFor<Rule>().ShouldBeFalse();
+ container.Model.HasImplementationsFor<IEngine>().ShouldBeTrue();
+ }
+
+ [Test]
+ public void remove_an_open_type()
+ {
+ container.Model.EjectAndRemove(typeof(IService<>));
+
+ container.Model.HasImplementationsFor(typeof (IService<>));
+
+ container.TryGetInstance<IService<string>>().ShouldBeNull();
+ }
+
+ [Test]
+ public void remove_an_open_type_with_a_filter()
+ {
+ container.Model.EjectAndRemovePluginTypes(t => t == typeof(IService<>));
+
+ container.Model.HasImplementationsFor(typeof(IService<>));
+
+ container.TryGetInstance<IService<string>>().ShouldBeNull();
+ }
+
+ [Test]
public void can_iterate_through_families_including_both_generics_and_normal()
{
// +1 for "IContainer" itself
- container.Model.PluginTypes.Count().ShouldEqual(5);
+ container.Model.PluginTypes.Count().ShouldEqual(8);
container.Model.PluginTypes.Each(x => Debug.WriteLine(x.PluginType.FullName));
}
@@ -82,7 +139,7 @@
[Test]
public void get_all_instances_from_the_top()
{
- container.Model.AllInstances.Count().ShouldEqual(8);
+ container.Model.AllInstances.Count().ShouldEqual(11);
}
[Test]
@@ -105,5 +162,42 @@
{
container.Model.For<ISomething>().HasImplementations().ShouldBeFalse();
}
+
+ [Test]
+ public void get_all_possibles()
+ {
+ // Startable1 is a singleton
+
+ var startable1 = container.GetInstance<Startable1>();
+ startable1.WasStarted.ShouldBeFalse();
+
+ container.Model.GetAllPossible<IStartable>()
+ .ToArray()
+ .Each(x => x.Start())
+ .Each(x => x.WasStarted.ShouldBeTrue());
+
+ startable1.WasStarted.ShouldBeTrue();
+ }
}
+
+
+ public interface IStartable
+ {
+ void Start();
+ bool WasStarted { get; }
+ }
+
+ public class Startable : IStartable
+ {
+ public void Start()
+ {
+ WasStarted = true;
+ }
+
+ public bool WasStarted { get; private set; }
+ }
+
+ public class Startable1 : Startable{}
+ public class Startable2 : Startable{}
+ public class Startable3 : Startable{}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|