|
From: <jer...@us...> - 2008-10-02 18:44:12
|
Revision: 162
http://structuremap.svn.sourceforge.net/structuremap/?rev=162&view=rev
Author: jeremydmiller
Date: 2008-10-02 18:44:00 +0000 (Thu, 02 Oct 2008)
Log Message:
-----------
assembly scanning updates
Modified Paths:
--------------
trunk/Source/StructureMap/Configuration/DSL/Registry.cs
trunk/Source/StructureMap/Configuration/GraphBuilder.cs
trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs
trunk/Source/StructureMap/Graph/AssemblyScanner.cs
trunk/Source/StructureMap/Graph/PluginFamily.cs
trunk/Source/StructureMap/Graph/PluginGraph.cs
trunk/Source/StructureMap.Testing/Configuration/DSL/RegistryTester.cs
trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs
trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj
Added Paths:
-----------
trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs
Modified: trunk/Source/StructureMap/Configuration/DSL/Registry.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -9,6 +9,7 @@
{
public class Registry : RegistryExpressions
{
+ private readonly List<Action> _basicActions = new List<Action>();
private readonly List<Action<PluginGraph>> _actions = new List<Action<PluginGraph>>();
public Registry()
@@ -24,6 +25,11 @@
// no-op;
}
+ protected void registerAction(Action action)
+ {
+ _basicActions.Add(action);
+ }
+
internal void addExpression(Action<PluginGraph> alteration)
{
_actions.Add(alteration);
@@ -35,10 +41,8 @@
graph.Log.StartSource("Registry: " + TypePath.GetAssemblyQualifiedName(GetType()));
- foreach (Action<PluginGraph> action in _actions)
- {
- action(graph);
- }
+ _basicActions.ForEach(action => action());
+ _actions.ForEach(action => action(graph));
graph.Registries.Add(this);
}
Modified: trunk/Source/StructureMap/Configuration/GraphBuilder.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/GraphBuilder.cs 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap/Configuration/GraphBuilder.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -33,7 +33,6 @@
_systemScanner = new AssemblyScanner();
_systemScanner.Assembly(Assembly.GetExecutingAssembly());
- _systemScanner.IgnoreRegistries();
_systemGraph = new PluginGraph(_systemScanner);
}
Modified: trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs
===================================================================
--- trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -147,6 +147,12 @@
_validationErrors.ForEach(e => e.Write(writer));
_errors.ForEach(e => e.Write(writer));
+ writer.WriteLine();
+ writer.WriteLine();
+
+
+ writer.WriteLine("StructureMap Failures: {0} Build/Configuration Failures and {1} Validation Errors", _errors.BuildErrors.Length, _validationErrors.Count);
+
return builder.ToString();
}
Modified: trunk/Source/StructureMap/Graph/AssemblyScanner.cs
===================================================================
--- trunk/Source/StructureMap/Graph/AssemblyScanner.cs 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap/Graph/AssemblyScanner.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -8,16 +8,25 @@
namespace StructureMap.Graph
{
+ public static class TypeExtensions
+ {
+ public static bool IsInNamespace(this Type type, string nameSpace)
+ {
+ return type.Namespace.StartsWith(nameSpace);
+ }
+ }
+
public class AssemblyScanner
{
private readonly List<Assembly> _assemblies = new List<Assembly>();
private readonly List<ITypeScanner> _scanners = new List<ITypeScanner>();
+ private readonly List<Predicate<Type>> _includes = new List<Predicate<Type>>();
+ private readonly List<Predicate<Type>> _excludes = new List<Predicate<Type>>();
public AssemblyScanner()
{
With<FamilyAttributeScanner>();
With<PluggableAttributeScanner>();
- With<FindRegistriesScanner>();
}
public int Count
@@ -25,6 +34,8 @@
get { return _assemblies.Count; }
}
+
+
public void ScanForAll(PluginGraph pluginGraph)
{
_assemblies.ForEach(assem => scanTypesInAssembly(assem, pluginGraph));
@@ -37,6 +48,9 @@
{
foreach (Type type in assembly.GetExportedTypes())
{
+ if (!isInTheIncludes(type)) continue;
+ if (isInTheExcludes(type)) continue;
+
_scanners.ForEach(scanner => scanner.Process(type, graph));
}
}
@@ -46,6 +60,31 @@
}
}
+ private bool isInTheExcludes(Type type)
+ {
+ if (_excludes.Count == 0) return false;
+
+ foreach (var exclude in _excludes)
+ {
+ if (exclude(type)) return true;
+ }
+
+ return false;
+ }
+
+ private bool isInTheIncludes(Type type)
+ {
+ if (_includes.Count == 0) return true;
+
+
+ foreach (var include in _includes)
+ {
+ if (include(type)) return true;
+ }
+
+ return false;
+ }
+
public void Assembly(Assembly assembly)
{
if (!_assemblies.Contains(assembly))
@@ -79,8 +118,15 @@
_scanners.Add(scanner);
}
+ public void WithDefaultConventions()
+ {
+ With<DefaultConventionScanner>();
+ }
+
public void With<T>() where T : ITypeScanner, new()
{
+ _scanners.RemoveAll(scanner => scanner is T);
+
ITypeScanner previous = _scanners.FirstOrDefault(scanner => scanner is T);
if (previous == null)
{
@@ -88,9 +134,9 @@
}
}
- public void IgnoreRegistries()
+ public void LookForRegistries()
{
- _scanners.RemoveAll(x => x is FindRegistriesScanner);
+ With<FindRegistriesScanner>();
}
public void TheCallingAssembly()
@@ -142,5 +188,46 @@
With(new FindAllTypesFilter(pluginType));
}
+ public void IgnoreStructureMapAttributes()
+ {
+ _scanners.RemoveAll(scanner => scanner is FamilyAttributeScanner);
+ _scanners.RemoveAll(scanner => scanner is PluggableAttributeScanner);
+ }
+
+
+ public void Exclude(Predicate<Type> exclude)
+ {
+ _excludes.Add(exclude);
+ }
+
+ public void ExcludeNamespace(string nameSpace)
+ {
+ Exclude(type => type.IsInNamespace(nameSpace));
+ }
+
+ public void ExcludeNamespaceContainingType<T>()
+ {
+ ExcludeNamespace(typeof(T).Namespace);
+ }
+
+ public void Include(Predicate<Type> predicate)
+ {
+ _includes.Add(predicate);
+ }
+
+ public void IncludeNamespace(string nameSpace)
+ {
+ Include(type => type.IsInNamespace(nameSpace));
+ }
+
+ public void IncludeNamespaceContainingType<T>()
+ {
+ IncludeNamespace(typeof (T).Namespace);
+ }
+
+ public void ExcludeType<T>()
+ {
+ Exclude(type => type == typeof (T));
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Graph/PluginFamily.cs
===================================================================
--- trunk/Source/StructureMap/Graph/PluginFamily.cs 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap/Graph/PluginFamily.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -346,5 +346,15 @@
AddPlugin(concreteType);
}
}
+
+ public void AddType(Type concreteType, string name)
+ {
+ if (!CanBeCast(_pluginType, concreteType)) return;
+
+ if (FindPlugin(name) == null)
+ {
+ AddPlugin(concreteType, name);
+ }
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Graph/PluginGraph.cs
===================================================================
--- trunk/Source/StructureMap/Graph/PluginGraph.cs 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap/Graph/PluginGraph.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -156,9 +156,22 @@
FindFamily(pluginType).AddType(concreteType);
}
+ public void AddType(Type pluginType, Type concreteType, string name)
+ {
+ FindFamily(pluginType).AddType(concreteType, name);
+ }
+
public void AddType(Type pluggedType)
{
_pluggedTypes.Add(pluggedType);
}
+
+ public void Configure(Action<Registry> action)
+ {
+ var registry = new Registry();
+ action(registry);
+
+ registry.ConfigurePluginGraph(this);
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap.Testing/Configuration/DSL/RegistryTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Configuration/DSL/RegistryTester.cs 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap.Testing/Configuration/DSL/RegistryTester.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -18,6 +18,8 @@
#endregion
+
+
[Test]
public void Equals_check_true()
{
@@ -59,6 +61,13 @@
Container container = new Container(registry);
}
+
+ [Test]
+ public void use_the_basic_actions_as_part_of_building_a_PluginGraph()
+ {
+ var container = new Container(new BasicActionRegistry());
+ container.GetInstance<IGateway>().ShouldBeOfType<Fake3Gateway>();
+ }
}
public class ConcreteWithNoConstructor
@@ -142,4 +151,12 @@
#endregion
}
+
+ public class BasicActionRegistry : Registry
+ {
+ public BasicActionRegistry()
+ {
+ registerAction(() => ForRequestedType<IGateway>().TheDefaultIsConcreteType<Fake3Gateway>());
+ }
+ }
}
\ No newline at end of file
Added: trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs (rev 0)
+++ trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -0,0 +1,299 @@
+using System;
+using NUnit.Framework;
+using StructureMap.Configuration.DSL;
+using StructureMap.Graph;
+using StructureMap.Testing.Widget;
+using StructureMap.Testing.Widget5;
+
+namespace StructureMap.Testing.Graph
+{
+ public class TestingRegistry : Registry
+ {
+ public static bool WasUsed;
+
+ public TestingRegistry()
+ {
+ WasUsed = true;
+
+ ForRequestedType<Rule>().TheDefault.IsThis(new ColorRule("Green"));
+ }
+
+ public static void Reset()
+ {
+ WasUsed = false;
+ }
+ }
+
+ [TestFixture]
+ public class AssemblyScannerTester
+ {
+ #region Setup/Teardown
+
+ [SetUp]
+ public void SetUp()
+ {
+ TestingRegistry.Reset();
+
+ theGraph = null;
+ }
+
+ #endregion
+
+ private PluginGraph theGraph;
+
+ private void Scan(Action<AssemblyScanner> action)
+ {
+ var scanner = new AssemblyScanner();
+ action(scanner);
+ theGraph = new PluginGraph();
+ scanner.ScanForAll(theGraph);
+ }
+
+
+ private void shouldHaveFamily<T>()
+ {
+ theGraph.PluginFamilies.Contains(typeof (T)).ShouldBeTrue();
+ }
+
+ private void shouldNotHaveFamily<T>()
+ {
+ theGraph.PluginFamilies.Contains(typeof (T)).ShouldBeFalse();
+ }
+
+ [Test]
+ public void AssemblyScanner_will_scan_for_attributes_by_default()
+ {
+ Scan(x => { x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>(); });
+
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+ [Test]
+ public void is_in_namespace()
+ {
+ GetType().IsInNamespace("blah").ShouldBeFalse();
+ GetType().IsInNamespace("StructureMap").ShouldBeTrue();
+ GetType().IsInNamespace("StructureMap.Testing").ShouldBeTrue();
+ GetType().IsInNamespace("StructureMap.Testing.Graph").ShouldBeTrue();
+ GetType().IsInNamespace("StructureMap.Testing.Graph.Something").ShouldBeFalse();
+ }
+
+ [Test]
+ public void Only_scan_for_registries_ignores_attributes()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.IgnoreStructureMapAttributes();
+ });
+
+ shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+ [Test]
+ public void scan_but_ignore_registries_by_default()
+ {
+ Scan(x =>
+ {
+ x.TheCallingAssembly();
+ });
+
+ TestingRegistry.WasUsed.ShouldBeFalse();
+ }
+
+ [Test]
+ public void Search_for_registries_by_default()
+ {
+ Scan(x =>
+ {
+ x.TheCallingAssembly();
+ x.LookForRegistries();
+ });
+
+ TestingRegistry.WasUsed.ShouldBeTrue();
+ }
+
+ [Test]
+ public void test_the_family_attribute_scanner()
+ {
+ var scanner = new FamilyAttributeScanner();
+ var graph = new PluginGraph();
+
+ scanner.Process(typeof (ITypeThatHasAttributeButIsNotInRegistry), graph);
+ graph.PluginFamilies.Contains(typeof (ITypeThatHasAttributeButIsNotInRegistry)).ShouldBeTrue();
+
+ scanner.Process(GetType(), graph);
+ graph.PluginFamilies.Contains(GetType()).ShouldBeFalse();
+ }
+
+ [Test]
+ public void use_a_dual_exclude()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.Exclude(type => type == typeof (ITypeThatHasAttributeButIsNotInRegistry));
+ x.Exclude(type => type == typeof (IInterfaceInWidget5));
+ });
+
+ shouldNotHaveFamily<IInterfaceInWidget5>();
+ shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+
+ [Test]
+ public void use_a_dual_exclude2()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.Exclude(type => type == typeof (ITypeThatHasAttributeButIsNotInRegistry));
+ x.Exclude(type => type == GetType());
+ });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+ [Test]
+ public void use_a_single_exclude()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.Exclude(type => type == typeof (ITypeThatHasAttributeButIsNotInRegistry));
+ });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+
+ [Test]
+ public void use_a_single_exclude2()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.ExcludeNamespace("StructureMap.Testing.Widget5");
+ });
+
+ shouldNotHaveFamily<IInterfaceInWidget5>();
+ shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+
+ [Test]
+ public void use_a_single_exclude3()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.ExcludeNamespaceContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ });
+
+ shouldNotHaveFamily<IInterfaceInWidget5>();
+ shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+
+ [Test]
+ public void use_a_single_exclude_of_type()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.ExcludeType<ITypeThatHasAttributeButIsNotInRegistry>();
+ });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldNotHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+ [Test]
+ public void Use_a_single_include_predicate()
+ {
+ Scan(x => { x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>(); });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.Include(type => type == typeof (ITypeThatHasAttributeButIsNotInRegistry));
+ });
+
+ shouldNotHaveFamily<IInterfaceInWidget5>();
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+
+ [Test]
+ public void Use_a_single_include_predicate_2()
+ {
+ Scan(x => { x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>(); });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.IncludeNamespace(typeof (ITypeThatHasAttributeButIsNotInRegistry).Namespace);
+ });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+
+ [Test]
+ public void Use_a_single_include_predicate_3()
+ {
+ Scan(x => { x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>(); });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.IncludeNamespaceContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+
+ [Test]
+ public void use_two_predicates_for_includes()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.Include(type => type == typeof (ITypeThatHasAttributeButIsNotInRegistry));
+ x.Include(type => type == typeof (IInterfaceInWidget5));
+ });
+
+ shouldHaveFamily<IInterfaceInWidget5>();
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+
+
+ [Test]
+ public void use_two_predicates_for_includes2()
+ {
+ Scan(x =>
+ {
+ x.AssemblyContainingType<ITypeThatHasAttributeButIsNotInRegistry>();
+ x.Include(type => type == typeof (ITypeThatHasAttributeButIsNotInRegistry));
+ x.Include(type => type == GetType());
+ });
+
+ shouldNotHaveFamily<IInterfaceInWidget5>();
+ shouldHaveFamily<ITypeThatHasAttributeButIsNotInRegistry>();
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs 2008-10-02 18:44:00 UTC (rev 162)
@@ -73,6 +73,17 @@
}
[Test]
+ public void add_type_by_name()
+ {
+ var family = new PluginFamily(typeof(IServiceProvider));
+ family.AddType(typeof(DataTable), "table");
+
+ family.PluginCount.ShouldEqual(1);
+
+ family.FindPlugin("table").ShouldNotBeNull();
+ }
+
+ [Test]
public void AddAPluggedType()
{
var family = new PluginFamily(typeof (IWidget));
Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj
===================================================================
--- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-10-02 01:05:46 UTC (rev 161)
+++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-10-02 18:44:00 UTC (rev 162)
@@ -215,6 +215,7 @@
<Compile Include="Graph\ArrayConstructorTester.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Graph\AssemblyScannerTester.cs" />
<Compile Include="Graph\ContainerConstructorAttributeTester.cs">
<SubType>Code</SubType>
</Compile>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|