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