|
From: <jer...@us...> - 2009-12-26 17:37:37
|
Revision: 297
http://structuremap.svn.sourceforge.net/structuremap/?rev=297&view=rev
Author: jeremydmiller
Date: 2009-12-26 17:37:30 +0000 (Sat, 26 Dec 2009)
Log Message:
-----------
Redo of the assembly scanning. Mild optimization
Modified Paths:
--------------
trunk/Source/StructureMap/Graph/AssemblyScanner.cs
trunk/Source/StructureMap/Graph/IHeavyweightTypeScanner.cs
trunk/Source/StructureMap/Graph/PluginGraph.cs
trunk/Source/StructureMap/StructureMap.csproj
Added Paths:
-----------
trunk/Source/StructureMap/Graph/CompositeFilter.cs
trunk/Source/StructureMap/Graph/CompositePredicate.cs
trunk/Source/StructureMap/Graph/IAssemblyScanner.cs
Modified: trunk/Source/StructureMap/Graph/AssemblyScanner.cs
===================================================================
--- trunk/Source/StructureMap/Graph/AssemblyScanner.cs 2009-12-26 05:45:56 UTC (rev 296)
+++ trunk/Source/StructureMap/Graph/AssemblyScanner.cs 2009-12-26 17:37:30 UTC (rev 297)
@@ -5,194 +5,44 @@
using System.Linq;
using System.Reflection;
using StructureMap.TypeRules;
+using StructureMap.Util;
namespace StructureMap.Graph
{
- public interface IAssemblyScanner
+ public class TypePool
{
- #region Designating Assemblies
+ private readonly Cache<Assembly, Type[]> _types = new Cache<Assembly, Type[]>();
- /// <summary>
- /// Add an Assembly to the scanning operation
- /// </summary>
- /// <param name="assembly"></param>
- void Assembly(Assembly assembly);
+ public TypePool(PluginGraph graph)
+ {
+ _types.OnMissing = assembly =>
+ {
+ try
+ {
+ return assembly.GetExportedTypes();
+ }
+ catch (Exception ex)
+ {
+ graph.Log.RegisterError(170, ex, assembly.FullName);
+ return new Type[0];
+ }
+ };
+ }
- /// <summary>
- /// Add an Assembly by name to the scanning operation
- /// </summary>
- /// <param name="assemblyName"></param>
- void Assembly(string assemblyName);
-
- /// <summary>
- /// Add the currently executing Assembly to the scanning operation
- /// </summary>
- void TheCallingAssembly();
-
- /// <summary>
- /// Add the Assembly that contains type T to the scanning operation
- /// </summary>
- /// <typeparam name="T"></typeparam>
- void AssemblyContainingType<T>();
-
- /// <summary>
- /// Add the Assembly that contains type to the scanning operation
- /// </summary>
- /// <param name="type"></param>
- void AssemblyContainingType(Type type);
-
- /// <summary>
- /// Sweep the designated path and add any Assembly's found in this folder to the
- /// scanning operation
- /// </summary>
- /// <param name="path"></param>
- void AssembliesFromPath(string path);
-
- /// <summary>
- /// Sweep the designated path and add any Assembly's found in this folder to the
- /// scanning operation. The assemblyFilter can be used to filter or limit the
- /// Assembly's that are picked up.
- /// </summary>
- /// <param name="path"></param>
- /// <param name="assemblyFilter"></param>
- void AssembliesFromPath(string path, Predicate<Assembly> assemblyFilter);
-
- /// <summary>
- /// Sweep the application base directory of current app domain and add any Assembly's
- /// found to the scanning operation.
- /// </summary>
- void AssembliesFromApplicationBaseDirectory();
-
- /// <summary>
- /// Sweep the application base directory of current app domain and add any Assembly's
- /// found to the scanning operation. The assemblyFilter can be used to filter or limit the
- /// Assembly's that are picked up.
- /// </summary>
- void AssembliesFromApplicationBaseDirectory(Predicate<Assembly> assemblyFilter);
-
- #endregion
-
- #region Adding TypeScanners
-
- /// <summary>
- /// Adds an ITypeScanner object to the scanning operation
- /// </summary>
- /// <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
- /// added to PluginType "ISomething"
- /// </summary>
- void WithDefaultConventions();
-
- /// <summary>
- /// Creates and adds a new ITypeScanner of type T to this scanning operation
- /// </summary>
- /// <typeparam name="T"></typeparam>
- void With<T>() where T : ITypeScanner, new();
-
- #endregion
-
- #region Other options
-
- /// <summary>
- /// Directs the scanning operation to automatically detect and include any Registry
- /// classes found in the Assembly's being scanned
- /// </summary>
- void LookForRegistries();
-
- /// <summary>
- /// Add all concrete types of the Plugin Type as Instances of Plugin Type
- /// </summary>
- /// <typeparam name="PLUGINTYPE"></typeparam>
- FindAllTypesFilter AddAllTypesOf<PLUGINTYPE>();
-
- /// <summary>
- /// Add all concrete types of the Plugin Type as Instances of Plugin Type
- /// </summary>
- /// <param name="pluginType"></param>
- FindAllTypesFilter AddAllTypesOf(Type pluginType);
-
- /// <summary>
- /// Makes this scanning operation ignore all [PluginFamily] and [Pluggable] attributes
- /// </summary>
- void IgnoreStructureMapAttributes();
-
- #endregion
-
- #region Filtering types
-
- /// <summary>
- /// Exclude types that match the Predicate from being scanned
- /// </summary>
- /// <param name="exclude"></param>
- void Exclude(Predicate<Type> exclude);
-
- /// <summary>
- /// Exclude all types in this nameSpace or its children from the scanning operation
- /// </summary>
- /// <param name="nameSpace"></param>
- void ExcludeNamespace(string nameSpace);
-
- /// <summary>
- /// Exclude all types in this nameSpace or its children from the scanning operation
- /// </summary>
- /// <typeparam name="T"></typeparam>
- void ExcludeNamespaceContainingType<T>();
-
- /// <summary>
- /// Only include types matching the Predicate in the scanning operation. You can
- /// use multiple Include() calls in a single scanning operation
- /// </summary>
- /// <param name="predicate"></param>
- void Include(Predicate<Type> predicate);
-
- /// <summary>
- /// Only include types from this nameSpace or its children in the scanning operation. You can
- /// use multiple Include() calls in a single scanning operation
- /// </summary>
- /// <param name="nameSpace"></param>
- void IncludeNamespace(string nameSpace);
-
- /// <summary>
- /// Only include types from this nameSpace or its children in the scanning operation. You can
- /// use multiple Include() calls in a single scanning operation
- /// </summary>
- /// <typeparam name="T"></typeparam>
- void IncludeNamespaceContainingType<T>();
-
- /// <summary>
- /// Exclude this specific type from the scanning operation
- /// </summary>
- /// <typeparam name="T"></typeparam>
- void ExcludeType<T>();
-
- // ... Other methods
-
- #endregion
-
- // ... Other methods
-
- /// <summary>
- /// Scans for PluginType's and Concrete Types that close the given open generic type
- /// </summary>
- /// <example>
- ///
- /// </example>
- /// <param name="openGenericType"></param>
- void ConnectImplementationsToTypesClosing(Type openGenericType);
+ public IEnumerable<Type> For(IEnumerable<Assembly> assemblies, CompositeFilter<Type> filter)
+ {
+ return assemblies.SelectMany(x => _types[x].Where(filter.Matches));
+ }
}
+
public class AssemblyScanner : IAssemblyScanner
{
private readonly List<Assembly> _assemblies = new List<Assembly>();
- private readonly List<Predicate<Type>> _excludes = new List<Predicate<Type>>();
+ private readonly CompositeFilter<Type> _filter = new CompositeFilter<Type>();
+
private readonly List<IHeavyweightTypeScanner> _heavyweightScanners = new List<IHeavyweightTypeScanner>();
- private readonly List<Predicate<Type>> _includes = new List<Predicate<Type>>();
+
private readonly List<ITypeScanner> _scanners = new List<ITypeScanner>();
public AssemblyScanner()
@@ -292,9 +142,9 @@
}
- public void Exclude(Predicate<Type> exclude)
+ public void Exclude(Func<Type, bool> exclude)
{
- _excludes.Add(exclude);
+ _filter.Excludes += exclude;
}
public void ExcludeNamespace(string nameSpace)
@@ -307,9 +157,9 @@
ExcludeNamespace(typeof (T).Namespace);
}
- public void Include(Predicate<Type> predicate)
+ public void Include(Func<Type, bool> predicate)
{
- _includes.Add(predicate);
+ _filter.Includes += predicate;
}
public void IncludeNamespace(string nameSpace)
@@ -381,31 +231,17 @@
internal void ScanForAll(PluginGraph pluginGraph)
{
- TypeMapBuilder heavyweightScan = configureHeavyweightScan();
+ //TypeMapBuilder heavyweightScan = configureHeavyweightScan();
- _assemblies.ForEach(assem => scanTypesInAssembly(assem, pluginGraph));
-
- performHeavyweightScan(pluginGraph, heavyweightScan);
- }
-
- private void scanTypesInAssembly(Assembly assembly, PluginGraph graph)
- {
- try
+ pluginGraph.Types.For(_assemblies, _filter).Each(type =>
{
- foreach (Type type in assembly.GetExportedTypes())
- {
- if (!isInTheIncludes(type)) continue;
- if (isInTheExcludes(type)) continue;
+ _scanners.Each(x => x.Process(type, pluginGraph));
+ });
- _scanners.ForEach(scanner => scanner.Process(type, graph));
- }
- }
- catch (Exception ex)
- {
- graph.Log.RegisterError(170, ex, assembly.FullName);
- }
+ //performHeavyweightScan(pluginGraph, heavyweightScan);
}
+
private TypeMapBuilder configureHeavyweightScan()
{
var typeMapBuilder = new TypeMapBuilder();
@@ -416,6 +252,7 @@
return typeMapBuilder;
}
+ [Obsolete]
private void performHeavyweightScan(PluginGraph pluginGraph, TypeMapBuilder typeMapBuilder)
{
IEnumerable<TypeMap> typeMaps = typeMapBuilder.GetTypeMaps();
@@ -423,31 +260,6 @@
typeMapBuilder.Dispose();
}
- 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 bool Contains(string assemblyName)
{
foreach (Assembly assembly in _assemblies)
Added: trunk/Source/StructureMap/Graph/CompositeFilter.cs
===================================================================
--- trunk/Source/StructureMap/Graph/CompositeFilter.cs (rev 0)
+++ trunk/Source/StructureMap/Graph/CompositeFilter.cs 2009-12-26 17:37:30 UTC (rev 297)
@@ -0,0 +1,16 @@
+namespace StructureMap.Graph
+{
+ public class CompositeFilter<T>
+ {
+ private readonly CompositePredicate<T> _excludes = new CompositePredicate<T>();
+ private readonly CompositePredicate<T> _includes = new CompositePredicate<T>();
+
+ public CompositePredicate<T> Includes { get { return _includes; } set { } }
+ public CompositePredicate<T> Excludes { get { return _excludes; } set { } }
+
+ public bool Matches(T target)
+ {
+ return Includes.MatchesAny(target) && Excludes.DoesNotMatcheAny(target);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/Source/StructureMap/Graph/CompositePredicate.cs
===================================================================
--- trunk/Source/StructureMap/Graph/CompositePredicate.cs (rev 0)
+++ trunk/Source/StructureMap/Graph/CompositePredicate.cs 2009-12-26 17:37:30 UTC (rev 297)
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace StructureMap.Graph
+{
+ public class CompositePredicate<T>
+ {
+ private readonly List<Func<T, bool>> _list = new List<Func<T, bool>>();
+ private Func<T, bool> _matchesAll = x => true;
+ private Func<T, bool> _matchesAny = x => true;
+ private Func<T, bool> _matchesNone = x => false;
+
+ public void Add(Func<T, bool> filter)
+ {
+ _matchesAll = x => _list.All(predicate => predicate(x));
+ _matchesAny = x => _list.Any(predicate => predicate(x));
+ _matchesNone = x => !MatchesAny(x);
+
+ _list.Add(filter);
+ }
+
+ public static CompositePredicate<T> operator +(CompositePredicate<T> invokes, Func<T, bool> filter)
+ {
+ invokes.Add(filter);
+ return invokes;
+ }
+
+ public bool MatchesAll(T target)
+ {
+ return _matchesAll(target);
+ }
+
+ public bool MatchesAny(T target)
+ {
+ return _matchesAny(target);
+ }
+
+ public bool MatchesNone(T target)
+ {
+ return _matchesNone(target);
+ }
+
+ public bool DoesNotMatcheAny(T target)
+ {
+ return _list.Count == 0 ? true : !MatchesAny(target);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/Source/StructureMap/Graph/IAssemblyScanner.cs
===================================================================
--- trunk/Source/StructureMap/Graph/IAssemblyScanner.cs (rev 0)
+++ trunk/Source/StructureMap/Graph/IAssemblyScanner.cs 2009-12-26 17:37:30 UTC (rev 297)
@@ -0,0 +1,184 @@
+using System;
+using System.Reflection;
+
+namespace StructureMap.Graph
+{
+ public interface IAssemblyScanner
+ {
+ #region Designating Assemblies
+
+ /// <summary>
+ /// Add an Assembly to the scanning operation
+ /// </summary>
+ /// <param name="assembly"></param>
+ void Assembly(Assembly assembly);
+
+ /// <summary>
+ /// Add an Assembly by name to the scanning operation
+ /// </summary>
+ /// <param name="assemblyName"></param>
+ void Assembly(string assemblyName);
+
+ /// <summary>
+ /// Add the currently executing Assembly to the scanning operation
+ /// </summary>
+ void TheCallingAssembly();
+
+ /// <summary>
+ /// Add the Assembly that contains type T to the scanning operation
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ void AssemblyContainingType<T>();
+
+ /// <summary>
+ /// Add the Assembly that contains type to the scanning operation
+ /// </summary>
+ /// <param name="type"></param>
+ void AssemblyContainingType(Type type);
+
+ /// <summary>
+ /// Sweep the designated path and add any Assembly's found in this folder to the
+ /// scanning operation
+ /// </summary>
+ /// <param name="path"></param>
+ void AssembliesFromPath(string path);
+
+ /// <summary>
+ /// Sweep the designated path and add any Assembly's found in this folder to the
+ /// scanning operation. The assemblyFilter can be used to filter or limit the
+ /// Assembly's that are picked up.
+ /// </summary>
+ /// <param name="path"></param>
+ /// <param name="assemblyFilter"></param>
+ void AssembliesFromPath(string path, Predicate<Assembly> assemblyFilter);
+
+ /// <summary>
+ /// Sweep the application base directory of current app domain and add any Assembly's
+ /// found to the scanning operation.
+ /// </summary>
+ void AssembliesFromApplicationBaseDirectory();
+
+ /// <summary>
+ /// Sweep the application base directory of current app domain and add any Assembly's
+ /// found to the scanning operation. The assemblyFilter can be used to filter or limit the
+ /// Assembly's that are picked up.
+ /// </summary>
+ void AssembliesFromApplicationBaseDirectory(Predicate<Assembly> assemblyFilter);
+
+ #endregion
+
+ #region Adding TypeScanners
+
+ /// <summary>
+ /// Adds an ITypeScanner object to the scanning operation
+ /// </summary>
+ /// <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
+ /// added to PluginType "ISomething"
+ /// </summary>
+ void WithDefaultConventions();
+
+ /// <summary>
+ /// Creates and adds a new ITypeScanner of type T to this scanning operation
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ void With<T>() where T : ITypeScanner, new();
+
+ #endregion
+
+ #region Other options
+
+ /// <summary>
+ /// Directs the scanning operation to automatically detect and include any Registry
+ /// classes found in the Assembly's being scanned
+ /// </summary>
+ void LookForRegistries();
+
+ /// <summary>
+ /// Add all concrete types of the Plugin Type as Instances of Plugin Type
+ /// </summary>
+ /// <typeparam name="PLUGINTYPE"></typeparam>
+ FindAllTypesFilter AddAllTypesOf<PLUGINTYPE>();
+
+ /// <summary>
+ /// Add all concrete types of the Plugin Type as Instances of Plugin Type
+ /// </summary>
+ /// <param name="pluginType"></param>
+ FindAllTypesFilter AddAllTypesOf(Type pluginType);
+
+ /// <summary>
+ /// Makes this scanning operation ignore all [PluginFamily] and [Pluggable] attributes
+ /// </summary>
+ void IgnoreStructureMapAttributes();
+
+ #endregion
+
+ #region Filtering types
+
+ /// <summary>
+ /// Exclude types that match the Predicate from being scanned
+ /// </summary>
+ /// <param name="exclude"></param>
+ void Exclude(Func<Type, bool> exclude);
+
+ /// <summary>
+ /// Exclude all types in this nameSpace or its children from the scanning operation
+ /// </summary>
+ /// <param name="nameSpace"></param>
+ void ExcludeNamespace(string nameSpace);
+
+ /// <summary>
+ /// Exclude all types in this nameSpace or its children from the scanning operation
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ void ExcludeNamespaceContainingType<T>();
+
+ /// <summary>
+ /// Only include types matching the Predicate in the scanning operation. You can
+ /// use multiple Include() calls in a single scanning operation
+ /// </summary>
+ /// <param name="predicate"></param>
+ void Include(Func<Type, bool> predicate);
+
+ /// <summary>
+ /// Only include types from this nameSpace or its children in the scanning operation. You can
+ /// use multiple Include() calls in a single scanning operation
+ /// </summary>
+ /// <param name="nameSpace"></param>
+ void IncludeNamespace(string nameSpace);
+
+ /// <summary>
+ /// Only include types from this nameSpace or its children in the scanning operation. You can
+ /// use multiple Include() calls in a single scanning operation
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ void IncludeNamespaceContainingType<T>();
+
+ /// <summary>
+ /// Exclude this specific type from the scanning operation
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ void ExcludeType<T>();
+
+ // ... Other methods
+
+ #endregion
+
+ // ... Other methods
+
+ /// <summary>
+ /// Scans for PluginType's and Concrete Types that close the given open generic type
+ /// </summary>
+ /// <example>
+ ///
+ /// </example>
+ /// <param name="openGenericType"></param>
+ void ConnectImplementationsToTypesClosing(Type openGenericType);
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Graph/IHeavyweightTypeScanner.cs
===================================================================
--- trunk/Source/StructureMap/Graph/IHeavyweightTypeScanner.cs 2009-12-26 05:45:56 UTC (rev 296)
+++ trunk/Source/StructureMap/Graph/IHeavyweightTypeScanner.cs 2009-12-26 17:37:30 UTC (rev 297)
@@ -7,6 +7,7 @@
namespace StructureMap.Graph
{
+ [Obsolete]
public interface IHeavyweightTypeScanner
{
void Process(PluginGraph graph, IEnumerable<TypeMap> typeMaps);
Modified: trunk/Source/StructureMap/Graph/PluginGraph.cs
===================================================================
--- trunk/Source/StructureMap/Graph/PluginGraph.cs 2009-12-26 05:45:56 UTC (rev 296)
+++ trunk/Source/StructureMap/Graph/PluginGraph.cs 2009-12-26 17:37:30 UTC (rev 297)
@@ -33,6 +33,33 @@
void AddType(Type pluggedType);
}
+
+ public class WeakReference<T>
+ {
+ private readonly Func<T> _builder;
+ private readonly WeakReference _reference;
+
+ public WeakReference(Func<T> builder)
+ {
+ _builder = builder;
+ _reference = new WeakReference(_builder());
+ }
+
+ public T Value
+ {
+ get
+ {
+ if (!_reference.IsAlive)
+ {
+ _reference.Target = _builder();
+ }
+
+ return (T)_reference.Target;
+ }
+ }
+ }
+
+
/// <summary>
/// Models the runtime configuration of a StructureMap Container
/// </summary>
@@ -47,17 +74,21 @@
private readonly List<AssemblyScanner> _scanners = new List<AssemblyScanner>();
private GraphLog _log = new GraphLog();
private bool _sealed;
+ private readonly WeakReference<TypePool> _types;
public PluginGraph()
{
_pluginFamilies = new PluginFamilyCollection(this);
+ _types = new WeakReference<TypePool>(() => new TypePool(this));
}
- public PluginGraph(AssemblyScanner assemblies)
+ public TypePool Types
{
- _pluginFamilies = new PluginFamilyCollection(this);
- _scanners.Add(assemblies);
+ get
+ {
+ return _types.Value;
+ }
}
public List<Registry> Registries { get { return _registries; } }
Modified: trunk/Source/StructureMap/StructureMap.csproj
===================================================================
--- trunk/Source/StructureMap/StructureMap.csproj 2009-12-26 05:45:56 UTC (rev 296)
+++ trunk/Source/StructureMap/StructureMap.csproj 2009-12-26 17:37:30 UTC (rev 297)
@@ -356,9 +356,12 @@
<Compile Include="ErrorMessages.cs" />
<Compile Include="Example.cs" />
<Compile Include="Extensions.cs" />
+ <Compile Include="Graph\CompositeFilter.cs" />
+ <Compile Include="Graph\CompositePredicate.cs" />
<Compile Include="Graph\FamilyAttributeScanner.cs" />
<Compile Include="Graph\FindAllTypesFilter.cs" />
<Compile Include="Graph\FindRegistriesScanner.cs" />
+ <Compile Include="Graph\IAssemblyScanner.cs" />
<Compile Include="Graph\IHeavyweightTypeScanner.cs" />
<Compile Include="Graph\ITypeScanner.cs" />
<Compile Include="Graph\PluggableAttributeScanner.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|