|
From: <jer...@us...> - 2009-12-26 18:18:54
|
Revision: 298
http://structuremap.svn.sourceforge.net/structuremap/?rev=298&view=rev
Author: jeremydmiller
Date: 2009-12-26 18:18:44 +0000 (Sat, 26 Dec 2009)
Log Message:
-----------
Overhaul of the "single implementation scanning" feature
Modified Paths:
--------------
trunk/Source/StructureMap/Graph/AssemblyScanner.cs
trunk/Source/StructureMap/Graph/IAssemblyScanner.cs
trunk/Source/StructureMap/StructureMap.csproj
trunk/Source/StructureMap/TypeExtensions.cs
trunk/Source/StructureMap.Testing/Graph/SingleImplementationScannerTester.cs
trunk/Source/StructureMap.Testing/TypeExtensionsTester.cs
Added Paths:
-----------
trunk/Source/StructureMap/Graph/ImplementationMap.cs
Removed Paths:
-------------
trunk/Source/StructureMap/Graph/SingleImplementationScanner.cs
Modified: trunk/Source/StructureMap/Graph/AssemblyScanner.cs
===================================================================
--- trunk/Source/StructureMap/Graph/AssemblyScanner.cs 2009-12-26 17:37:30 UTC (rev 297)
+++ trunk/Source/StructureMap/Graph/AssemblyScanner.cs 2009-12-26 18:18:44 UTC (rev 298)
@@ -41,9 +41,8 @@
private readonly List<Assembly> _assemblies = new List<Assembly>();
private readonly CompositeFilter<Type> _filter = new CompositeFilter<Type>();
- private readonly List<IHeavyweightTypeScanner> _heavyweightScanners = new List<IHeavyweightTypeScanner>();
-
private readonly List<ITypeScanner> _scanners = new List<ITypeScanner>();
+ private readonly List<Action<PluginGraph>> _postScanningActions = new List<Action<PluginGraph>>();
public AssemblyScanner()
{
@@ -74,13 +73,6 @@
_scanners.Add(scanner);
}
- public void With(IHeavyweightTypeScanner heavyweightScanner)
- {
- if (_heavyweightScanners.Contains(heavyweightScanner)) return;
-
- _heavyweightScanners.Add(heavyweightScanner);
- }
-
public void WithDefaultConventions()
{
With<DefaultConventionScanner>();
@@ -182,6 +174,15 @@
With(new GenericConnectionScanner(openGenericType));
}
+
+ private readonly ImplementationMap _implementationMap = new ImplementationMap();
+
+ public void SingleImplementationsOfInterface()
+ {
+ _scanners.Fill(_implementationMap);
+ _postScanningActions.Add(graph => _implementationMap.RegisterSingleImplementations(graph));
+ }
+
public void AssembliesFromApplicationBaseDirectory()
{
AssembliesFromApplicationBaseDirectory(a => true);
@@ -231,35 +232,15 @@
internal void ScanForAll(PluginGraph pluginGraph)
{
- //TypeMapBuilder heavyweightScan = configureHeavyweightScan();
-
pluginGraph.Types.For(_assemblies, _filter).Each(type =>
{
_scanners.Each(x => x.Process(type, pluginGraph));
});
- //performHeavyweightScan(pluginGraph, heavyweightScan);
+ _postScanningActions.Each(x => x(pluginGraph));
}
- private TypeMapBuilder configureHeavyweightScan()
- {
- var typeMapBuilder = new TypeMapBuilder();
- if (_heavyweightScanners.Count > 0)
- {
- With(typeMapBuilder);
- }
- return typeMapBuilder;
- }
-
- [Obsolete]
- private void performHeavyweightScan(PluginGraph pluginGraph, TypeMapBuilder typeMapBuilder)
- {
- IEnumerable<TypeMap> typeMaps = typeMapBuilder.GetTypeMaps();
- _heavyweightScanners.ForEach(scanner => scanner.Process(pluginGraph, typeMaps));
- typeMapBuilder.Dispose();
- }
-
public bool Contains(string assemblyName)
{
foreach (Assembly assembly in _assemblies)
Modified: trunk/Source/StructureMap/Graph/IAssemblyScanner.cs
===================================================================
--- trunk/Source/StructureMap/Graph/IAssemblyScanner.cs 2009-12-26 17:37:30 UTC (rev 297)
+++ trunk/Source/StructureMap/Graph/IAssemblyScanner.cs 2009-12-26 18:18:44 UTC (rev 298)
@@ -75,8 +75,6 @@
/// <param name="scanner"></param>
void With(ITypeScanner scanner);
- void With(IHeavyweightTypeScanner heavyweightScanner);
-
/// <summary>
/// Adds the DefaultConventionScanner to the scanning operations. I.e., a concrete
/// class named "Something" that implements "ISomething" will be automatically
@@ -180,5 +178,12 @@
/// </example>
/// <param name="openGenericType"></param>
void ConnectImplementationsToTypesClosing(Type openGenericType);
+
+ /// <summary>
+ /// Directs the scanning to automatically register any type that is the single
+ /// implementation of an interface against that interface.
+ /// The filters apply
+ /// </summary>
+ void SingleImplementationsOfInterface();
}
}
\ No newline at end of file
Added: trunk/Source/StructureMap/Graph/ImplementationMap.cs
===================================================================
--- trunk/Source/StructureMap/Graph/ImplementationMap.cs (rev 0)
+++ trunk/Source/StructureMap/Graph/ImplementationMap.cs 2009-12-26 18:18:44 UTC (rev 298)
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using StructureMap.TypeRules;
+using StructureMap.Util;
+
+namespace StructureMap.Graph
+{
+ public class ImplementationMap : ITypeScanner
+ {
+ private readonly Cache<Type, List<Type>> _types = new Cache<Type, List<Type>>(t => new List<Type>());
+
+ public void Register(Type interfaceType, Type concreteType)
+ {
+ _types[interfaceType].Add(concreteType);
+ }
+
+ public void RegisterType(Type type)
+ {
+ if (!type.CanBeCreated()) return;
+
+ type.GetInterfaces().Where(i => i.IsVisible).Each(i => Register(i, type));
+ }
+
+ public void Process(Type type, PluginGraph graph)
+ {
+ RegisterType(type);
+ }
+
+ public void RegisterSingleImplementations(PluginGraph graph)
+ {
+ _types.Each((pluginType, types) =>
+ {
+ if (types.Count == 1)
+ {
+ graph.AddType(pluginType, types[0]);
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
Deleted: trunk/Source/StructureMap/Graph/SingleImplementationScanner.cs
===================================================================
--- trunk/Source/StructureMap/Graph/SingleImplementationScanner.cs 2009-12-26 17:37:30 UTC (rev 297)
+++ trunk/Source/StructureMap/Graph/SingleImplementationScanner.cs 2009-12-26 18:18:44 UTC (rev 298)
@@ -1,16 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-
-namespace StructureMap.Graph
-{
- public class SingleImplementationScanner : IHeavyweightTypeScanner
- {
- public void Process(PluginGraph graph, IEnumerable<TypeMap> typeMaps)
- {
- foreach (TypeMap map in typeMaps.Where(map => map.ConcreteTypes.Count == 1))
- {
- graph.AddType(map.PluginType, map.ConcreteTypes[0]);
- }
- }
- }
-}
\ No newline at end of file
Modified: trunk/Source/StructureMap/StructureMap.csproj
===================================================================
--- trunk/Source/StructureMap/StructureMap.csproj 2009-12-26 17:37:30 UTC (rev 297)
+++ trunk/Source/StructureMap/StructureMap.csproj 2009-12-26 18:18:44 UTC (rev 298)
@@ -362,11 +362,10 @@
<Compile Include="Graph\FindAllTypesFilter.cs" />
<Compile Include="Graph\FindRegistriesScanner.cs" />
<Compile Include="Graph\IAssemblyScanner.cs" />
- <Compile Include="Graph\IHeavyweightTypeScanner.cs" />
+ <Compile Include="Graph\ImplementationMap.cs" />
<Compile Include="Graph\ITypeScanner.cs" />
<Compile Include="Graph\PluggableAttributeScanner.cs" />
<Compile Include="Graph\PluginCache.cs" />
- <Compile Include="Graph\SingleImplementationScanner.cs" />
<Compile Include="IContext.cs" />
<Compile Include="Pipeline\Arguments.cs" />
<Compile Include="Pipeline\ArrayCoercion.cs" />
Modified: trunk/Source/StructureMap/TypeExtensions.cs
===================================================================
--- trunk/Source/StructureMap/TypeExtensions.cs 2009-12-26 17:37:30 UTC (rev 297)
+++ trunk/Source/StructureMap/TypeExtensions.cs 2009-12-26 18:18:44 UTC (rev 298)
@@ -7,6 +7,13 @@
{
public static class BasicExtensions
{
+ public static void Fill<T>(this IList<T> list, T value)
+ {
+ if (list.Contains(value)) return;
+ list.Add(value);
+ }
+
+
public static void TryGet<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key,
Action<TValue> action)
{
@@ -139,6 +146,19 @@
return type.FullName;
}
+ public static bool CanBeCreated(this Type type)
+ {
+ return type.IsConcrete() && Constructor.HasConstructors(type);
+ }
+
+ public static IEnumerable<Type> AllInterfaces(this Type type)
+ {
+ foreach (var @interface in type.GetInterfaces())
+ {
+ yield return @interface;
+ }
+ }
+
/// <summary>
/// Determines if the pluggedType can be upcast to the pluginType
/// </summary>
Modified: trunk/Source/StructureMap.Testing/Graph/SingleImplementationScannerTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Graph/SingleImplementationScannerTester.cs 2009-12-26 17:37:30 UTC (rev 297)
+++ trunk/Source/StructureMap.Testing/Graph/SingleImplementationScannerTester.cs 2009-12-26 18:18:44 UTC (rev 298)
@@ -13,7 +13,7 @@
typeof (Type).IsValueType.ShouldBeFalse();
}
- [Test, Ignore("Come back to this")]
+ [Test]
public void registers_plugins_that_only_have_a_single_implementation()
{
var container = new Container(registry =>
@@ -22,7 +22,7 @@
{
x.TheCallingAssembly();
x.IncludeNamespaceContainingType<SingleImplementationScannerTester>();
- x.With(new SingleImplementationScanner());
+ x.SingleImplementationsOfInterface();
});
});
Modified: trunk/Source/StructureMap.Testing/TypeExtensionsTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/TypeExtensionsTester.cs 2009-12-26 17:37:30 UTC (rev 297)
+++ trunk/Source/StructureMap.Testing/TypeExtensionsTester.cs 2009-12-26 18:18:44 UTC (rev 298)
@@ -102,5 +102,22 @@
Assert.IsTrue(typeof (string).IsString());
Assert.IsFalse(typeof (int).IsString());
}
+
+ [Test]
+ public void get_all_interfaces()
+ {
+ typeof(C3).AllInterfaces().ShouldHaveTheSameElementsAs(typeof(I1), typeof(I2), typeof(I3));
+ typeof(C2).AllInterfaces().ShouldHaveTheSameElementsAs(typeof(I1), typeof(I2));
+ typeof(C1).AllInterfaces().ShouldHaveTheSameElementsAs(typeof(I1));
+ }
}
+
+
+ public interface I1{}
+ public interface I2{}
+ public interface I3{}
+
+ public class C1 : I1{}
+ public class C2 : C1, I2{}
+ public class C3 : C2, I3{}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|