From: <jer...@us...> - 2008-05-26 17:39:12
|
Revision: 99 http://structuremap.svn.sourceforge.net/structuremap/?rev=99&view=rev Author: jeremydmiller Date: 2008-05-26 10:39:08 -0700 (Mon, 26 May 2008) Log Message: ----------- cleaning up all the Profile FI and generics problems. Little refactoring to simplify the FI development, validation development, the ValidationBuildSession Modified Paths: -------------- trunk/Source/StructureMap/Attributes/ValidationMethodAttribute.cs trunk/Source/StructureMap/BuildSession.cs trunk/Source/StructureMap/Configuration/ConfigurationParser.cs trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/ProfileExpression.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/ScanAssembliesExpression.cs trunk/Source/StructureMap/Configuration/DSL/Registry.cs trunk/Source/StructureMap/Configuration/ProfileBuilder.cs trunk/Source/StructureMap/Diagnostics/WhatDoIHaveWriter.cs trunk/Source/StructureMap/Graph/AssemblyScanner.cs trunk/Source/StructureMap/Graph/PluginFamily.cs trunk/Source/StructureMap/Graph/PluginGraph.cs trunk/Source/StructureMap/Graph/TypePath.cs trunk/Source/StructureMap/InstanceManager.cs trunk/Source/StructureMap/ObjectFactory.cs trunk/Source/StructureMap/Pipeline/ConfiguredInstance.cs trunk/Source/StructureMap/Pipeline/ConstructorInstance.cs trunk/Source/StructureMap/Pipeline/Instance.cs trunk/Source/StructureMap/Pipeline/LiteralInstance.cs trunk/Source/StructureMap/Pipeline/Profile.cs trunk/Source/StructureMap/PipelineGraph.cs trunk/Source/StructureMap/PluginGraphBuilder.cs trunk/Source/StructureMap/StructureMap.csproj trunk/Source/StructureMap/StructureMapConfiguration.cs trunk/Source/StructureMap/StructureMapException.resx trunk/Source/StructureMap.Testing/AlternativeConfigurationTester.cs trunk/Source/StructureMap.Testing/BuildSessionTester.cs trunk/Source/StructureMap.Testing/Configuration/ConfigurationParserBuilderTester.cs trunk/Source/StructureMap.Testing/Configuration/DSL/ProfileExpressionTester.cs trunk/Source/StructureMap.Testing/Configuration/DSL/RegistryTester.cs trunk/Source/StructureMap.Testing/Configuration/InlineInstanceDefinitionInProfileAndMachineNodesTester.cs trunk/Source/StructureMap.Testing/Configuration/ProfileBuilderTester.cs trunk/Source/StructureMap.Testing/Container/ExceptionHandling/StructureMapExceptionTester.cs trunk/Source/StructureMap.Testing/Container/FullStackFacadeTester.cs trunk/Source/StructureMap.Testing/Container/InstanceFactoryTester.cs trunk/Source/StructureMap.Testing/Container/InstanceManagerTester.cs trunk/Source/StructureMap.Testing/DataAccess/CommandFactoryTester.cs trunk/Source/StructureMap.Testing/DataAccess/ExecutionStates/AutoCommitExecutionStateTester.cs trunk/Source/StructureMap.Testing/DataAccess/ExecutionStates/TransactionalExecutionStateTester.cs trunk/Source/StructureMap.Testing/DataAccess/TemplatedCommandTester.cs trunk/Source/StructureMap.Testing/GenericsAcceptanceTester.cs trunk/Source/StructureMap.Testing/GenericsIntegrationTester.cs trunk/Source/StructureMap.Testing/Graph/PluginFamilyTester.cs trunk/Source/StructureMap.Testing/Graph/PluginGraphTester.cs trunk/Source/StructureMap.Testing/Graph/SetterInjectionTester.cs trunk/Source/StructureMap.Testing/Graph/TypePathTester.cs trunk/Source/StructureMap.Testing/ObjectFactoryTester.cs trunk/Source/StructureMap.Testing/Pipeline/ConfiguredInstanceTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj trunk/Source/StructureMap.Testing/StructureMapConfigurationTester.cs trunk/Source/StructureMap.Testing/TestData/DataMother.cs trunk/Source/StructureMap.Testing/TestData/DefaultProfileConfig.xml trunk/Source/StructureMap.Testing/TestData/ObjectMother.config trunk/Source/StructureMap.Testing/TestData/SampleConfig.xml trunk/Source/StructureMap.Testing.GenericWidgets/Widgets.cs trunk/Source/StructureMap.Testing.Widget/IWidget.cs trunk/Source/StructureMap.sln Added Paths: ----------- trunk/Source/HTML/ trunk/Source/HTML/HTML.csproj trunk/Source/StructureMap/Delegates.cs trunk/Source/StructureMap/Diagnostics/BuildError.cs trunk/Source/StructureMap/Diagnostics/Error.cs trunk/Source/StructureMap/Diagnostics/ErrorCollection.cs trunk/Source/StructureMap/Diagnostics/GraphLog.cs trunk/Source/StructureMap/Diagnostics/InstanceToken.cs trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs trunk/Source/StructureMap/Exceptions/StructureMapConfigurationException.cs trunk/Source/StructureMap.Testing/Diagnostics/IntegrationTester.cs trunk/Source/StructureMap.Testing/Diagnostics/ValidationBuildSessionTester.cs Removed Paths: ------------- trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceDefaultExpression.cs trunk/Source/StructureMap/Configuration/DSL/IExpression.cs trunk/Source/StructureMap/Diagnostics/Tokens.cs Added: trunk/Source/HTML/HTML.csproj =================================================================== --- trunk/Source/HTML/HTML.csproj (rev 0) +++ trunk/Source/HTML/HTML.csproj 2008-05-26 17:39:08 UTC (rev 99) @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{A6358895-641F-4CC2-BE8E-C61EBE1DBEB9}</ProjectGuid> + <OutputType>Exe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>HTML</RootNamespace> + <AssemblyName>HTML</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Modified: trunk/Source/StructureMap/Attributes/ValidationMethodAttribute.cs =================================================================== --- trunk/Source/StructureMap/Attributes/ValidationMethodAttribute.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Attributes/ValidationMethodAttribute.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -51,19 +51,5 @@ return returnValue; } - - - /// <summary> - /// Executes the marked validation methods, if any, on an object - /// </summary> - /// <param name="target"></param> - public static void CallValidationMethods(object target) - { - MethodInfo[] methods = GetValidationMethods(target.GetType()); - foreach (MethodInfo method in methods) - { - method.Invoke(target, new object[0]); - } - } } } \ No newline at end of file Modified: trunk/Source/StructureMap/BuildSession.cs =================================================================== --- trunk/Source/StructureMap/BuildSession.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/BuildSession.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -10,7 +10,7 @@ { private readonly InterceptorLibrary _interceptorLibrary; private readonly PipelineGraph _pipelineGraph; - private InstanceCache _cache = new InstanceCache(); + private readonly InstanceCache _cache = new InstanceCache(); public BuildSession(PipelineGraph pipelineGraph, InterceptorLibrary interceptorLibrary) { @@ -24,6 +24,12 @@ } + + protected PipelineGraph pipelineGraph + { + get { return _pipelineGraph; } + } + #region IBuildSession Members public object CreateInstance(Type pluginType, string name) @@ -37,7 +43,7 @@ return CreateInstance(pluginType, instance); } - public object CreateInstance(Type pluginType, Instance instance) + public virtual object CreateInstance(Type pluginType, Instance instance) { object result = _cache.Get(pluginType, instance); Modified: trunk/Source/StructureMap/Configuration/ConfigurationParser.cs =================================================================== --- trunk/Source/StructureMap/Configuration/ConfigurationParser.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/ConfigurationParser.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -31,6 +31,8 @@ #endregion + public string Description = string.Empty; + private readonly XmlMementoCreator _mementoCreator; private readonly XmlNode _structureMapNode; private string _filePath = string.Empty; Modified: trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs =================================================================== --- trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Xml; @@ -8,12 +7,12 @@ { public class ConfigurationParserBuilder { - private readonly List<XmlNode> _nodes = new List<XmlNode>(); + private readonly GraphLog _log; + private readonly List<ConfigurationParser> _parsers = new List<ConfigurationParser>(); private readonly List<string> _otherFiles = new List<string>(); private bool _ignoreDefaultFile = false; - private readonly GraphLog _log; - private bool _useAndEnforceExistenceOfDefaultFile = false; private bool _pullConfigurationFromAppConfig; + private bool _useAndEnforceExistenceOfDefaultFile = false; public ConfigurationParserBuilder(GraphLog log) @@ -37,10 +36,7 @@ public bool PullConfigurationFromAppConfig { get { return _pullConfigurationFromAppConfig; } - set - { - _pullConfigurationFromAppConfig = value; - } + set { _pullConfigurationFromAppConfig = value; } } // TODO: Clean up with 3.5 @@ -53,53 +49,47 @@ if (shouldUseStructureMapConfigFileAt(pathToStructureMapConfig)) { _log.Try(delegate() - { - ConfigurationParser parser = ConfigurationParser.FromFile(pathToStructureMapConfig); - list.Add(parser); - }).AndReportErrorAs(100, pathToStructureMapConfig); + { + ConfigurationParser parser = ConfigurationParser.FromFile(pathToStructureMapConfig); + list.Add(parser); + }).AndReportErrorAs(100, pathToStructureMapConfig); } foreach (string filename in _otherFiles) { _log.Try(delegate() - { - ConfigurationParser parser = ConfigurationParser.FromFile(filename); - list.Add(parser); - }).AndReportErrorAs(160, filename); + { + ConfigurationParser parser = ConfigurationParser.FromFile(filename); + parser.Description = filename; + list.Add(parser); + }).AndReportErrorAs(160, filename); } if (_pullConfigurationFromAppConfig) { _log.Try(delegate() - { - IList<XmlNode> appConfigNodes = StructureMapConfigurationSection.GetStructureMapConfiguration(); - foreach (XmlNode appConfigNode in appConfigNodes) - { - IncludeNode(appConfigNode); - } - }).AndLogAnyErrors(); - + { + IList<XmlNode> appConfigNodes = StructureMapConfigurationSection.GetStructureMapConfiguration(); + foreach (XmlNode appConfigNode in appConfigNodes) + { + IncludeNode(appConfigNode, string.Empty); + } + }).AndLogAnyErrors(); } - // TODO -- some error handling here, or somewhere else. Need to create ConfigurationParser - // as soon as the node is added to try to determine errors - foreach (XmlNode node in _nodes) - { - ConfigurationParser parser = new ConfigurationParser(node); - list.Add(parser); - } + list.AddRange(_parsers); - foreach (ConfigurationParser parser in list.ToArray()) + foreach (ConfigurationParser parser in list.ToArray()) { parser.ForEachFile(_log, delegate(string filename) + { + _log.Try(delegate() { - _log.Try(delegate() - { - ConfigurationParser childParser = ConfigurationParser.FromFile(filename); - list.Add(childParser); - }).AndReportErrorAs(150, filename); - }); + ConfigurationParser childParser = ConfigurationParser.FromFile(filename); + list.Add(childParser); + }).AndReportErrorAs(150, filename); + }); } @@ -109,8 +99,8 @@ private bool shouldUseStructureMapConfigFileAt(string pathToStructureMapConfig) { return - (_useAndEnforceExistenceOfDefaultFile || - File.Exists(pathToStructureMapConfig)) && !_ignoreDefaultFile; + (_useAndEnforceExistenceOfDefaultFile || + File.Exists(pathToStructureMapConfig)) && !_ignoreDefaultFile; } @@ -119,15 +109,19 @@ _otherFiles.Add(filename); } - public void IncludeNode(XmlNode node) + + public void IncludeNode(XmlNode node, string description) { - _nodes.Add(node); + ConfigurationParser parser = new ConfigurationParser(node); + parser.Description = description; + + _parsers.Add(parser); } public static ConfigurationParser[] GetParsers(XmlNode node, GraphLog log) { ConfigurationParserBuilder builder = new ConfigurationParserBuilder(log); - builder.IncludeNode(node); + builder.IncludeNode(node, string.Empty); builder.IgnoreDefaultFile = true; return builder.GetParsers(); Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -10,31 +10,28 @@ /// <summary> /// Represents the parameters for creating instances of a given Type /// </summary> - public class CreatePluginFamilyExpression<PLUGINTYPE> : IExpression + public class CreatePluginFamilyExpression<PLUGINTYPE> { private readonly List<Action<PluginFamily>> _alterations = new List<Action<PluginFamily>>(); private readonly List<Action<PluginGraph>> _children = new List<Action<PluginGraph>>(); private readonly Type _pluginType; private readonly InstanceScope _scope = InstanceScope.PerRequest; - public CreatePluginFamilyExpression() + public CreatePluginFamilyExpression(Registry registry) { _pluginType = typeof (PLUGINTYPE); - } - #region IExpression Members + registry.addExpression(delegate(PluginGraph graph) + { + PluginFamily family = graph.FindFamily(_pluginType); + family.SetScopeTo(_scope); - void IExpression.Configure(PluginGraph graph) - { - PluginFamily family = graph.FindFamily(_pluginType); - family.SetScopeTo(_scope); - - // TODO: clean up with 3.5 - _children.ForEach(delegate(Action<PluginGraph> action) { action(graph); }); - _alterations.ForEach(delegate(Action<PluginFamily> action) { action(family); }); + // TODO: clean up with 3.5 + _children.ForEach(delegate(Action<PluginGraph> action) { action(graph); }); + _alterations.ForEach(delegate(Action<PluginFamily> action) { action(family); }); + }); } - #endregion // TODO: 3.5, Try alterAndContinue(f => {}); private CreatePluginFamilyExpression<PLUGINTYPE> alterAndContinue(Action<PluginFamily> action) @@ -51,10 +48,10 @@ public CreatePluginFamilyExpression<PLUGINTYPE> TheDefaultIs(Instance instance) { return alterAndContinue(delegate(PluginFamily family) - { - family.AddInstance(instance); - family.DefaultInstanceKey = instance.Name; - }); + { + family.AddInstance(instance); + family.DefaultInstanceKey = instance.Name; + }); } public CreatePluginFamilyExpression<PLUGINTYPE> AddInstance(Instance instance) @@ -76,10 +73,10 @@ ExpressionValidator.ValidatePluggabilityOf(typeof (CONCRETETYPE)).IntoPluginType(_pluginType); return alterAndContinue(delegate(PluginFamily family) - { - Plugin plugin = family.Plugins.FindOrCreate(typeof(CONCRETETYPE), true); - family.DefaultInstanceKey = plugin.ConcreteKey; - }); + { + Plugin plugin = family.Plugins.FindOrCreate(typeof (CONCRETETYPE), true); + family.DefaultInstanceKey = plugin.ConcreteKey; + }); return this; } @@ -111,16 +108,16 @@ { _children.Add( delegate(PluginGraph graph) + { + InterceptionFunction function = delegate(object target) { - InterceptionFunction function = delegate(object target) - { - handler((PLUGINTYPE) target); - return target; - }; + handler((PLUGINTYPE) target); + return target; + }; - PluginTypeInterceptor interceptor = new PluginTypeInterceptor(typeof (PLUGINTYPE), function); - graph.InterceptorLibrary.AddInterceptor(interceptor); - }); + PluginTypeInterceptor interceptor = new PluginTypeInterceptor(typeof (PLUGINTYPE), function); + graph.InterceptorLibrary.AddInterceptor(interceptor); + }); return this; } @@ -129,12 +126,12 @@ { _children.Add( delegate(PluginGraph graph) - { - InterceptionFunction function = delegate(object target) { return handler((PLUGINTYPE) target); }; + { + InterceptionFunction function = delegate(object target) { return handler((PLUGINTYPE) target); }; - PluginTypeInterceptor interceptor = new PluginTypeInterceptor(typeof (PLUGINTYPE), function); - graph.InterceptorLibrary.AddInterceptor(interceptor); - }); + PluginTypeInterceptor interceptor = new PluginTypeInterceptor(typeof (PLUGINTYPE), function); + graph.InterceptorLibrary.AddInterceptor(interceptor); + }); return this; } @@ -146,15 +143,15 @@ public CreatePluginFamilyExpression<PLUGINTYPE> AddConcreteType<CONCRETETYPE>(string instanceName) { - ExpressionValidator.ValidatePluggabilityOf(typeof(CONCRETETYPE)).IntoPluginType(typeof(PLUGINTYPE)); + ExpressionValidator.ValidatePluggabilityOf(typeof (CONCRETETYPE)).IntoPluginType(typeof (PLUGINTYPE)); _alterations.Add( delegate(PluginFamily family) - { - Plugin plugin = new Plugin(typeof (CONCRETETYPE)); - plugin.ConcreteKey = instanceName; - family.Plugins.Add(plugin); - } + { + Plugin plugin = new Plugin(typeof (CONCRETETYPE)); + plugin.ConcreteKey = instanceName; + family.Plugins.Add(plugin); + } ); return this; @@ -175,7 +172,7 @@ public CreatePluginFamilyExpression<PLUGINTYPE> AliasConcreteType<PLUGGEDTYPE>(string concreteKey) { - ExpressionValidator.ValidatePluggabilityOf(typeof(PLUGGEDTYPE)).IntoPluginType(typeof(PLUGINTYPE)); + ExpressionValidator.ValidatePluggabilityOf(typeof (PLUGGEDTYPE)).IntoPluginType(typeof (PLUGINTYPE)); _alterations.Add(delegate(PluginFamily family) { family.AddPlugin(typeof (PLUGGEDTYPE), concreteKey); }); Deleted: trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceDefaultExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceDefaultExpression.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceDefaultExpression.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -1,77 +0,0 @@ -using System; -using StructureMap.Graph; -using StructureMap.Pipeline; - -namespace StructureMap.Configuration.DSL.Expressions -{ - /// <summary> - /// Use to express the instance of a PluginType for the containing Profile - /// </summary> - public class InstanceDefaultExpression - { - private readonly ProfileExpression _parent; - private readonly Type _pluginType; - private Instance _instance; - private string _instanceKey = string.Empty; - - public InstanceDefaultExpression(Type pluginType, ProfileExpression parent) - { - _pluginType = pluginType; - _parent = parent; - } - - /// <summary> - /// Use a named, preconfigured instance as the default instance for this profile - /// </summary> - /// <param name="instanceKey"></param> - /// <returns></returns> - public ProfileExpression UseNamedInstance(string instanceKey) - { - _instanceKey = instanceKey; - return _parent; - } - - internal void Configure(string profileName, PluginGraph pluginGraph) - { - // The profile instance is defined inline - if (_instance != null) - { - _instanceKey = Profile.InstanceKeyForProfile(profileName); - _instance.Name = _instanceKey; - pluginGraph.FindFamily(_pluginType).AddInstance(_instance); - } - - // Using a referenced key for the profile - else if (!string.IsNullOrEmpty(_instanceKey)) - { - _instance = new ReferencedInstance(_instanceKey); - } - - // Set the default instance in the Profile - if (_instance != null) - { - pluginGraph.ProfileManager.SetDefault(profileName, _pluginType, _instance); - } - - // Blow up if the Profile expression is not complete. - else - { - throw new StructureMapException(304, TypePath.GetAssemblyQualifiedName(_pluginType)); - } - } - - /// <summary> - /// Define the default instance of the PluginType for the containing Profile - /// </summary> - /// <param name="mementoBuilder"></param> - /// <returns></returns> - public ProfileExpression Use(Instance instance) - { - // TODO -- validate that the instance can be plugged into the PluginType - - _instance = instance; - - return _parent; - } - } -} \ No newline at end of file Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/ProfileExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/ProfileExpression.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/ProfileExpression.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -1,44 +1,152 @@ -using System.Collections.Generic; +using System; using StructureMap.Graph; +using StructureMap.Pipeline; namespace StructureMap.Configuration.DSL.Expressions { /// <summary> /// Expression class to help define a runtime Profile /// </summary> - public class ProfileExpression : IExpression + public class ProfileExpression { - private readonly List<InstanceDefaultExpression> _defaults = new List<InstanceDefaultExpression>(); private readonly string _profileName; + private readonly Registry _registry; - public ProfileExpression(string profileName) + public ProfileExpression(string profileName, Registry registry) { _profileName = profileName; + _registry = registry; } - #region IExpression Members - void IExpression.Configure(PluginGraph graph) + /// <summary> + /// Starts the definition of the default instance for the containing Profile + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns></returns> + public InstanceDefaultExpression<T> For<T>() { - foreach (InstanceDefaultExpression expression in _defaults) + return new InstanceDefaultExpression<T>(this); + } + + /// <summary> + /// Use statement to define the Profile defaults for a Generic type + /// </summary> + /// <param name="pluginType"></param> + /// <returns></returns> + public GenericDefaultExpression For(Type pluginType) + { + return new GenericDefaultExpression(this, pluginType); + } + + #region Nested type: InstanceDefaultExpression + + public class InstanceDefaultExpression<T> + { + private readonly ProfileExpression _parent; + private readonly string _profileName; + private readonly Registry _registry; + + public InstanceDefaultExpression(ProfileExpression parent) { - expression.Configure(_profileName, graph); + _parent = parent; + _registry = parent._registry; + _profileName = parent._profileName; } + + /// <summary> + /// Use a named, preconfigured instance as the default instance for this profile + /// </summary> + /// <param name="instanceKey"></param> + /// <returns></returns> + public ProfileExpression UseNamedInstance(string instanceKey) + { + _registry.addExpression(delegate(PluginGraph graph) + { + graph.SetDefault(_profileName, typeof(T), new ReferencedInstance(instanceKey)); + }); + + return _parent; + } + + /// <summary> + /// Define the default instance of the PluginType for the containing Profile + /// </summary> + /// <param name="mementoBuilder"></param> + /// <returns></returns> + public ProfileExpression Use(Instance instance) + { + instance.Name = "Default Instance for Profile " + _profileName; + + _registry.addExpression(delegate (PluginGraph graph) + { + graph.SetDefault(_profileName, typeof(T), instance); + }); + + return _parent; + } + + public ProfileExpression Use(Func<T> func) + { + ConstructorInstance instance = new ConstructorInstance(delegate { return func(); }); + return Use(instance); + } + + public ProfileExpression Use(T t) + { + LiteralInstance instance = new LiteralInstance(t); + return Use(instance); + } + + public ProfileExpression UseConcreteType<CONCRETETYPE>() + { + ConfiguredInstance instance = new ConfiguredInstance(typeof(CONCRETETYPE)); + return Use(instance); + } + + public ProfileExpression UsePrototypeOf(T template) + { + PrototypeInstance instance = new PrototypeInstance((ICloneable) template); + return Use(instance); + } } #endregion - /// <summary> - /// Starts the definition of the default instance for the containing Profile - /// </summary> - /// <typeparam name="T"></typeparam> - /// <returns></returns> - public InstanceDefaultExpression For<T>() + public class GenericDefaultExpression { - InstanceDefaultExpression defaultExpression = new InstanceDefaultExpression(typeof (T), this); - _defaults.Add(defaultExpression); + private readonly ProfileExpression _parent; + private readonly Type _pluginType; + private readonly Registry _registry; - return defaultExpression; + internal GenericDefaultExpression(ProfileExpression parent, Type pluginType) + { + _parent = parent; + _registry = parent._registry; + _pluginType = pluginType; + } + + public ProfileExpression UseConcreteType(Type concreteType) + { + ConfiguredInstance instance = new ConfiguredInstance(concreteType); + return Use(instance); + } + + public ProfileExpression Use(Instance instance) + { + _registry.addExpression(delegate(PluginGraph graph) + { + graph.SetDefault(_parent._profileName, _pluginType, instance); + }); + + return _parent; + } + + public ProfileExpression UseNamedInstance(string name) + { + ReferencedInstance instance = new ReferencedInstance(name); + return Use(instance); + } } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/ScanAssembliesExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/ScanAssembliesExpression.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/ScanAssembliesExpression.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -11,7 +11,7 @@ /// Expression that directs StructureMap to scan the named assemblies /// for [PluginFamily] and [Plugin] attributes /// </summary> - public class ScanAssembliesExpression : IExpression + public class ScanAssembliesExpression { private readonly List<Assembly> _assemblies = new List<Assembly>(); private readonly Registry _registry; @@ -19,20 +19,15 @@ public ScanAssembliesExpression(Registry registry) { _registry = registry; - } - - #region IExpression Members - - void IExpression.Configure(PluginGraph graph) - { - foreach (Assembly assembly in _assemblies) + _registry.addExpression(delegate(PluginGraph graph) { - graph.Assemblies.Add(assembly); - } + foreach (Assembly assembly in _assemblies) + { + graph.Assemblies.Add(assembly); + } + }); } - #endregion - public ScanAssembliesExpression IncludeTheCallingAssembly() { Assembly callingAssembly = findTheCallingAssembly(); @@ -74,11 +69,11 @@ public ScanAssembliesExpression AddAllTypesOf<PLUGINTYPE>() { _registry.addExpression(delegate(PluginGraph pluginGraph) - { - PluginFamily family = - pluginGraph.FindFamily(typeof (PLUGINTYPE)); - family.SearchForImplicitPlugins = true; - }); + { + PluginFamily family = + pluginGraph.FindFamily(typeof (PLUGINTYPE)); + family.SearchForImplicitPlugins = true; + }); return this; } Deleted: trunk/Source/StructureMap/Configuration/DSL/IExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/IExpression.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/DSL/IExpression.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -1,9 +0,0 @@ -using StructureMap.Graph; - -namespace StructureMap.Configuration.DSL -{ - public interface IExpression - { - void Configure(PluginGraph graph); - } -} \ No newline at end of file Modified: trunk/Source/StructureMap/Configuration/DSL/Registry.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/DSL/Registry.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -9,7 +9,7 @@ { public class Registry : IDisposable { - private readonly List<IExpression> _expressions = new List<IExpression>(); + private readonly List<Action<PluginGraph>> _actions = new List<Action<PluginGraph>>(); private readonly PluginGraph _graph; public Registry(PluginGraph graph) : this() @@ -40,21 +40,18 @@ // no-op; } - protected internal void addExpression(IExpression expression) + internal void addExpression(Action<PluginGraph> alteration) { - _expressions.Add(expression); + _actions.Add(alteration); } - internal void addExpression(PluginGraphAlteration alteration) - { - _expressions.Add(new BasicExpression(alteration)); - } - internal void ConfigurePluginGraph(PluginGraph graph) { - foreach (IExpression expression in _expressions) + graph.Log.StartSource("Registry: " + TypePath.GetAssemblyQualifiedName(GetType())); + + foreach (Action<PluginGraph> action in _actions) { - expression.Configure(graph); + action(graph); } } @@ -67,10 +64,7 @@ /// <returns></returns> public CreatePluginFamilyExpression<PLUGINTYPE> BuildInstancesOf<PLUGINTYPE>() { - CreatePluginFamilyExpression<PLUGINTYPE> expression = new CreatePluginFamilyExpression<PLUGINTYPE>(); - addExpression(expression); - - return expression; + return new CreatePluginFamilyExpression<PLUGINTYPE>(this); } /// <summary> @@ -83,10 +77,7 @@ /// <returns></returns> public CreatePluginFamilyExpression<PLUGINTYPE> ForRequestedType<PLUGINTYPE>() { - CreatePluginFamilyExpression<PLUGINTYPE> expression = new CreatePluginFamilyExpression<PLUGINTYPE>(); - addExpression(expression); - - return expression; + return new CreatePluginFamilyExpression<PLUGINTYPE>(this); } public IInstanceManager BuildInstanceManager() @@ -113,7 +104,10 @@ ConfiguredInstance instance = new ConfiguredInstance(); addExpression( - delegate(PluginGraph pluginGraph) { pluginGraph.FindFamily(typeof (PLUGINTYPE)).AddInstance(instance); }); + delegate(PluginGraph pluginGraph) + { + pluginGraph.FindFamily(typeof (PLUGINTYPE)).AddInstance(instance); + }); return instance; } @@ -200,8 +194,7 @@ /// <returns></returns> public ProfileExpression CreateProfile(string profileName) { - ProfileExpression expression = new ProfileExpression(profileName); - addExpression(expression); + ProfileExpression expression = new ProfileExpression(profileName, this); return expression; } @@ -254,12 +247,12 @@ delegate(PluginGraph pluginGraph) { pluginGraph.InterceptorLibrary.AddInterceptor(interceptor); }); } - public TypeInterceptorExpression IfTypeMatches(Predicate<Type> match) + public MatchedTypeInterceptor IfTypeMatches(Predicate<Type> match) { - TypeInterceptorExpression expression = new TypeInterceptorExpression(match); - _expressions.Add(expression); + MatchedTypeInterceptor interceptor = new MatchedTypeInterceptor(match); + _actions.Add(delegate(PluginGraph graph) { graph.InterceptorLibrary.AddInterceptor(interceptor); }); - return expression; + return interceptor; } @@ -269,33 +262,32 @@ /// <returns></returns> public ScanAssembliesExpression ScanAssemblies() { - ScanAssembliesExpression expression = new ScanAssembliesExpression(this); - addExpression(expression); + return new ScanAssembliesExpression(this); + } - return expression; + + public void AddInstanceOf(Type pluginType, Instance instance) + { + _actions.Add(delegate(PluginGraph graph) { graph.FindFamily(pluginType).AddInstance(instance); }); } + + public void AddInstanceOf<PLUGINTYPE>(Instance instance) + { + _actions.Add(delegate(PluginGraph graph) { graph.FindFamily(typeof (PLUGINTYPE)).AddInstance(instance); }); + } } - public class TypeInterceptorExpression : IExpression, TypeInterceptor + public class MatchedTypeInterceptor : TypeInterceptor { private readonly Predicate<Type> _match; private InterceptionFunction _interception; - internal TypeInterceptorExpression(Predicate<Type> match) + internal MatchedTypeInterceptor(Predicate<Type> match) { _match = match; } - #region IExpression Members - - void IExpression.Configure(PluginGraph graph) - { - graph.InterceptorLibrary.AddInterceptor(this); - } - - #endregion - #region TypeInterceptor Members public bool MatchesType(Type type) @@ -315,25 +307,4 @@ _interception = interception; } } - - internal delegate void PluginGraphAlteration(PluginGraph pluginGraph); - - internal class BasicExpression : IExpression - { - private readonly PluginGraphAlteration _alteration; - - internal BasicExpression(PluginGraphAlteration alteration) - { - _alteration = alteration; - } - - #region IExpression Members - - public void Configure(PluginGraph graph) - { - _alteration(graph); - } - - #endregion - } } \ No newline at end of file Modified: trunk/Source/StructureMap/Configuration/ProfileBuilder.cs =================================================================== --- trunk/Source/StructureMap/Configuration/ProfileBuilder.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Configuration/ProfileBuilder.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -47,10 +47,12 @@ public void OverrideProfile(TypePath typePath, string instanceKey) { - // TODO: what if the Type cannot be found? - - ReferencedInstance instance = new ReferencedInstance(instanceKey); - _profileManager.SetDefault(_lastProfile, typePath.FindType(), instance); + _pluginGraph.Log.Try(delegate() + { + ReferencedInstance instance = new ReferencedInstance(instanceKey); + _pluginGraph.SetDefault(_lastProfile, typePath.FindType(), instance); + + }).AndReportErrorAs(107, typePath.AssemblyQualifiedName); } public void AddMachine(string machineName, string profileName) Added: trunk/Source/StructureMap/Delegates.cs =================================================================== --- trunk/Source/StructureMap/Delegates.cs (rev 0) +++ trunk/Source/StructureMap/Delegates.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace StructureMap +{ + public delegate void Action(); + public delegate void Action<T>(T t); + public delegate void Action<T, T1>(T t, T1 t1); + public delegate T Func<T>(); + +} Added: trunk/Source/StructureMap/Diagnostics/BuildError.cs =================================================================== --- trunk/Source/StructureMap/Diagnostics/BuildError.cs (rev 0) +++ trunk/Source/StructureMap/Diagnostics/BuildError.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using StructureMap.Pipeline; + +namespace StructureMap.Diagnostics +{ + public class BuildDependency : IEquatable<BuildDependency> + { + public Instance Instance; + public Type PluginType; + + + public BuildDependency(Type pluginType, Instance instance) + { + Instance = instance; + PluginType = pluginType; + } + + + public bool Equals(BuildDependency buildDependency) + { + if (buildDependency == null) return false; + return Equals(Instance, buildDependency.Instance) && Equals(PluginType, buildDependency.PluginType); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) return true; + return Equals(obj as BuildDependency); + } + + public override int GetHashCode() + { + return (Instance != null ? Instance.GetHashCode() : 0) + 29*(PluginType != null ? PluginType.GetHashCode() : 0); + } + } + + public class BuildError + { + private readonly Instance _instance; + private readonly Type _pluginType; + private StructureMapException _exception; + private readonly List<BuildDependency> _dependencies = new List<BuildDependency>(); + + public BuildError(Type pluginType, Instance instance) + { + _instance = instance; + _pluginType = pluginType; + } + + public void AddDependency(BuildDependency dependency) + { + if (!_dependencies.Contains(dependency)) + { + _dependencies.Add(dependency); + } + } + + public List<BuildDependency> Dependencies + { + get { return _dependencies; } + } + + public Instance Instance + { + get { return _instance; } + } + + public Type PluginType + { + get { return _pluginType; } + } + + public StructureMapException Exception + { + get { return _exception; } + set { _exception = value; } + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Diagnostics/Error.cs =================================================================== --- trunk/Source/StructureMap/Diagnostics/Error.cs (rev 0) +++ trunk/Source/StructureMap/Diagnostics/Error.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -0,0 +1,108 @@ +using System; +using System.IO; +using System.Resources; + +namespace StructureMap.Diagnostics +{ + public class Error : IEquatable<Error> + { + private readonly int _code; + private readonly string _message; + private readonly string _stackTrace = string.Empty; + public InstanceToken Instance; + public string Source; + + + private Error(int code, string message) + { + _code = code; + _message = message; + } + + public Error(int errorCode, params object[] args) + { + _code = errorCode; + string template = getMessage(errorCode); + if (template == null) template = string.Empty; + + _message = string.Format(template, args); + } + + public Error(int errorCode, Exception ex, params object[] args) : this(errorCode, args) + { + _message += "\n\n" + ex.ToString(); + _stackTrace = ex.StackTrace; + } + + + public Error(StructureMapException exception) + { + _code = exception.ErrorCode; + _message = exception.Message; + _stackTrace = exception.StackTrace; + } + + + public int Code + { + get { return _code; } + } + + #region IEquatable<Error> Members + + public bool Equals(Error error) + { + if (error == null) return false; + if (_code != error._code) return false; + if (!Equals(_message, error._message)) return false; + if (!Equals(_stackTrace, error._stackTrace)) return false; + if (!Equals(Instance, error.Instance)) return false; + return true; + } + + #endregion + + private static string getMessage(int errorCode) + { + ResourceManager resources = new ResourceManager(typeof (StructureMapException)); + return resources.GetString(errorCode.ToString()); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) return true; + return Equals(obj as Error); + } + + public override int GetHashCode() + { + int result = _code; + result = 29*result + (_message != null ? _message.GetHashCode() : 0); + result = 29*result + (_stackTrace != null ? _stackTrace.GetHashCode() : 0); + result = 29*result + (Instance != null ? Instance.GetHashCode() : 0); + return result; + } + + + public override string ToString() + { + return string.Format("Error {0} -- {1}", _code, _message); + } + + public static Error FromMessage(int code, string message) + { + return new Error(code, message); + } + + public void Write(StringWriter writer) + { + // TODO: hit with an extension method for 3.5 + writer.WriteLine("Error: " + Code); + if (Instance != null) writer.WriteLine(Instance.ToString()); + writer.WriteLine("Source: " + Source); + + if (!string.IsNullOrEmpty(_message)) writer.WriteLine(_message); + if (!string.IsNullOrEmpty(_stackTrace)) writer.WriteLine(_stackTrace); + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Diagnostics/ErrorCollection.cs =================================================================== --- trunk/Source/StructureMap/Diagnostics/ErrorCollection.cs (rev 0) +++ trunk/Source/StructureMap/Diagnostics/ErrorCollection.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using StructureMap.Pipeline; + +namespace StructureMap.Diagnostics +{ + public class ErrorCollection + { + private readonly Dictionary<Instance, BuildError> _buildErrors = new Dictionary<Instance, BuildError>(); + private readonly List<Instance> _brokenInstances = new List<Instance>(); + + + public void LogError( + Instance instance, + Type pluginType, + StructureMapException ex, + IEnumerable<BuildDependency> dependencies) + { + if (_buildErrors.ContainsKey(instance)) + { + BuildError existingError = _buildErrors[instance]; + addDependenciesToError(instance, dependencies, existingError); + } + + if (_brokenInstances.Contains(instance)) + { + return; + } + + InstanceToken token = ((IDiagnosticInstance)instance).CreateToken(); + BuildError error = new BuildError(pluginType, instance); + error.Exception = ex; + + _buildErrors.Add(instance, error); + + addDependenciesToError(instance, dependencies, error); + } + + private void addDependenciesToError(Instance instance, IEnumerable<BuildDependency> dependencies, BuildError error) + { + foreach (BuildDependency dependency in dependencies) + { + if (_brokenInstances.Contains(instance)) + { + continue; + } + + error.AddDependency(dependency); + _brokenInstances.Add(dependency.Instance); + } + } + + public BuildError[] BuildErrors + { + get + { + BuildError[] errors = new BuildError[_buildErrors.Count]; + _buildErrors.Values.CopyTo(errors, 0); + + return errors; + } + } + + public BuildError Find(Type pluginType, string name) + { + foreach (KeyValuePair<Instance, BuildError> pair in _buildErrors) + { + BuildError error = pair.Value; + if (error.PluginType == pluginType && error.Instance.Name == name) + { + return error; + } + } + + return null; + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Diagnostics/GraphLog.cs =================================================================== --- trunk/Source/StructureMap/Diagnostics/GraphLog.cs (rev 0) +++ trunk/Source/StructureMap/Diagnostics/GraphLog.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using StructureMap.Exceptions; +using StructureMap.Graph; +using StructureMap.Pipeline; + +namespace StructureMap.Diagnostics +{ + public class GraphLog + { + private string _currentSource; + private readonly List<Error> _errors = new List<Error>(); + + public int ErrorCount + { + get { return _errors.Count; } + } + + public void StartSource(string description) + { + _currentSource = description; + } + + public void RegisterError(IDiagnosticInstance instance, int code, params object[] args) + { + Error error = new Error(code, args); + error.Instance = instance.CreateToken(); + addError(error); + } + + public void RegisterError(int code, params object[] args) + { + Error error = new Error(code, args); + addError(error); + } + + public void RegisterError(int code, Exception ex, params object[] args) + { + Error error = new Error(code, ex, args); + addError(error); + } + + + + public void RegisterError(StructureMapException ex) + { + Error error = new Error(ex); + addError(error); + } + + private void addError(Error error) + { + error.Source = _currentSource; + _errors.Add(error); + } + + public void AssertFailures() + { + if (_errors.Count == 0) + { + return; + } + + string message = WriteFailures(); + + throw new StructureMapConfigurationException(message); + } + + private string WriteFailures() + { + StringBuilder sb = new StringBuilder(); + StringWriter writer = new StringWriter(sb); + + writer.WriteLine("StructureMap configuration failures:"); + + foreach (Error error in _errors) + { + error.Write(writer); + writer.WriteLine("-----------------------------------------------------------------------------------------------------"); + writer.WriteLine(); + writer.WriteLine(); + } + + return sb.ToString(); + } + + public void AssertHasError(int errorCode, string message) + { + Error error = Error.FromMessage(errorCode, message); + if (!_errors.Contains(error)) + { + string msg = "Did not have the requested Error. Had:\n\n"; + foreach (Error err in _errors) + { + msg += err.ToString() + "\n"; + } + + throw new ApplicationException(msg); + } + } + + public void AssertHasError(int errorCode) + { + string message = "No error with code " + errorCode + "\nHad errors: "; + foreach (Error error in _errors) + { + message += error.Code + ", "; + if (error.Code == errorCode) + { + return; + } + } + + throw new ApplicationException(message); + } + + public void AssertHasNoError(int errorCode) + { + foreach (Error error in _errors) + { + if (error.Code == errorCode) + { + throw new ApplicationException("Has error " + errorCode); + } + } + } + + public TryAction Try(Action action) + { + return new TryAction(action, this); + } + + public class TryAction + { + private readonly Action _action; + private readonly GraphLog _log; + + internal TryAction(Action action, GraphLog log) + { + _action = action; + _log = log; + } + + public void AndReportErrorAs(int code, params object[] args) + { + try + { + _action(); + } + catch (Exception ex) + { + _log.RegisterError(code, ex, args); + } + } + + public void AndLogAnyErrors() + { + try + { + _action(); + } + catch (StructureMapException ex) + { + _log.RegisterError(ex); + } + catch (Exception ex) + { + _log.RegisterError(400, ex); + } + } + } + + } +} \ No newline at end of file Added: trunk/Source/StructureMap/Diagnostics/InstanceToken.cs =================================================================== --- trunk/Source/StructureMap/Diagnostics/InstanceToken.cs (rev 0) +++ trunk/Source/StructureMap/Diagnostics/InstanceToken.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -0,0 +1,57 @@ +using System; + +namespace StructureMap.Diagnostics +{ + public class InstanceToken : IEquatable<InstanceToken> + { + private readonly string _description; + private readonly string _name; + + public InstanceToken(string name, string description) + { + _name = name; + _description = description; + } + + + public string Name + { + get { return _name; } + } + + public string Description + { + get { return _description; } + } + + #region IEquatable<InstanceToken> Members + + public bool Equals(InstanceToken instanceToken) + { + if (instanceToken == null) return false; + if (!Equals(_name, instanceToken._name)) return false; + if (!Equals(_description, instanceToken._description)) return false; + return true; + } + + #endregion + + public override string ToString() + { + return string.Format("Instance '{0}' ({1})", _name, _description); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) return true; + return Equals(obj as InstanceToken); + } + + public override int GetHashCode() + { + int result = _name != null ? _name.GetHashCode() : 0; + result = 29*result + (_description != null ? _description.GetHashCode() : 0); + return result; + } + } +} \ No newline at end of file Deleted: trunk/Source/StructureMap/Diagnostics/Tokens.cs =================================================================== --- trunk/Source/StructureMap/Diagnostics/Tokens.cs 2008-05-17 01:25:16 UTC (rev 98) +++ trunk/Source/StructureMap/Diagnostics/Tokens.cs 2008-05-26 17:39:08 UTC (rev 99) @@ -1,368 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Resources; -using StructureMap.Graph; -using StructureMap.Pipeline; - -namespace StructureMap.Diagnostics -{ - public delegate void Action(); - - public class GraphLog - { - private readonly List<Source> _sources = new List<Source>(); - private Source _currentSource; - private readonly List<Error> _errors = new List<Error>(); - - pu... [truncated message content] |