diff --git a/src/Nancy.Testing.Tests/BrowserFixture.cs b/src/Nancy.Testing.Tests/BrowserFixture.cs index e3298edf13..872ca3ab97 100644 --- a/src/Nancy.Testing.Tests/BrowserFixture.cs +++ b/src/Nancy.Testing.Tests/BrowserFixture.cs @@ -6,7 +6,6 @@ namespace Nancy.Testing.Tests using System.Security.Cryptography.X509Certificates; using System.Text; using System.Linq; - using Nancy.Extensions; using Nancy.Tests; using Nancy.Helpers; @@ -14,6 +13,7 @@ namespace Nancy.Testing.Tests using Xunit; using FakeItEasy; using Nancy.Authentication.Forms; + using Nancy.Bootstrapper; public class BrowserFixture { @@ -26,7 +26,7 @@ public BrowserFixture() CookieBasedSessions.Enable(bootstrapper); - browser = new Browser(bootstrapper); + this.browser = new Browser(bootstrapper); } [Fact] @@ -538,7 +538,7 @@ public void Should_override_default_user_agent_when_explicitly_defined() // Then header.ShouldEqual(expectedHeaderValue); - } + } public class EchoModel { diff --git a/src/Nancy.Testing/ConfigurableBootstrapper.cs b/src/Nancy.Testing/ConfigurableBootstrapper.cs index 1edf98627b..6befe01e89 100644 --- a/src/Nancy.Testing/ConfigurableBootstrapper.cs +++ b/src/Nancy.Testing/ConfigurableBootstrapper.cs @@ -45,7 +45,8 @@ public class ConfigurableBootstrapper : NancyBootstrapperWithRequestContainerBas private bool allDiscoveredModules; private bool autoRegistrations = true; - + private bool disableAutoApplicationStartupRegistration; + private bool disableAutoRequestStartupRegistration; /// /// Initializes a new instance of the class. @@ -91,6 +92,12 @@ private static void PerformConventionBasedAssemblyLoading(Assembly testAssembly) LoadReferencesForAssemblyUnderTest(testAssemblyName); } + /// + /// Initialise the bootstrapper - can be used for adding pre/post hooks and + /// any other initialisation tasks that aren't specifically container setup + /// related + /// + /// Container instance for resolving types if required. protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines) { base.ApplicationStartup(container, pipelines); @@ -100,6 +107,14 @@ protected override void ApplicationStartup(TinyIoCContainer container, IPipeline } } + /// + /// Initialise the request - can be used for adding pre/post hooks and + /// any other per-request initialisation tasks that aren't specifically container setup + /// related + /// + /// Container + /// Current pipelines + /// Current context protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context) { base.RequestStartup(container, pipelines, context); @@ -187,7 +202,7 @@ private static void LoadReferencesForAssemblyUnderTest(string testAssemblyName) private static string GetSafePathExtension(string name) { - return Path.GetExtension(name) ?? String.Empty; + return Path.GetExtension(name) ?? string.Empty; } private IEnumerable Resolve() @@ -281,7 +296,39 @@ protected override IEnumerable BodyDeserializers /// protected override IEnumerable ApplicationStartupTasks { - get { return this.Resolve() ?? base.ApplicationStartupTasks; } + get + { + var tasks = base.ApplicationStartupTasks; + + var user = (this.Resolve() ?? Enumerable.Empty()).ToArray(); + + if (this.disableAutoApplicationStartupRegistration || user.Any()) + { + tasks = tasks.Where(x => x.Assembly.GetName().Name.StartsWith("Nancy", StringComparison.OrdinalIgnoreCase)); + } + + return tasks.Union(user); + } + } + + /// + /// Gets all request startup tasks + /// + protected override IEnumerable RequestStartupTasks + { + get + { + var tasks = base.RequestStartupTasks; + + var user = (this.Resolve() ?? Enumerable.Empty()).ToArray(); + + if (this.disableAutoRequestStartupRegistration || user.Any()) + { + tasks = tasks.Where(x => x.Assembly.GetName().Name.StartsWith("Nancy", StringComparison.OrdinalIgnoreCase)); + } + + return tasks.Union(user); + } } protected override DiagnosticsConfiguration DiagnosticsConfiguration @@ -1791,18 +1838,114 @@ public ConfigurableBootstrapperConfigurator ResponseNegotiator() where T : IR return this; } + /// + /// Configures the bootstrapper to use the provided instance of . + /// + /// The type of the that the bootstrapper should use. + /// A reference to the current . + public ConfigurableBootstrapperConfigurator ApplicationStartupTask() where T : IApplicationStartup + { + this.bootstrapper.registeredTypes.Add( + new TypeRegistration(typeof(IApplicationStartup), typeof(T))); + + return this; + } + + /// + /// Configures the bootstrapper to use the provided types. + /// + /// The types that should be used by the bootstrapper. + /// A reference to the current . + public ConfigurableBootstrapperConfigurator ApplicationStartupTasks(params Type[] applicationStartupTypes) + { + foreach (var type in applicationStartupTypes) + { + this.bootstrapper.registeredTypes.Add( + new TypeRegistration(typeof(IApplicationStartup), type)); + } + + return this; + } + + /// + /// Configures the bootstrapper to use the provided instance of . + /// + /// The type of the that the bootstrapper should use. + /// A reference to the current . + public ConfigurableBootstrapperConfigurator RequestStartupTask() where T : IRequestStartup + { + this.bootstrapper.registeredTypes.Add( + new TypeRegistration(typeof(IRequestStartup), typeof(T))); + + return this; + } + + /// + /// Configures the bootstrapper to use the provided types. + /// + /// The types that should be used by the bootstrapper. + /// A reference to the current . + public ConfigurableBootstrapperConfigurator RequestStartupTasks(params Type[] requestStartupTypes) + { + foreach (var type in requestStartupTypes) + { + this.bootstrapper.registeredTypes.Add( + new TypeRegistration(typeof(IRequestStartup), type)); + } + + return this; + } + + /// + /// Disables automatic registration of user-defined instances. It + /// will not prevent auto-registration of implementations bundled with Nancy. + /// + /// A reference to the current . + public ConfigurableBootstrapperConfigurator DisableAutoApplicationStartupRegistration() + { + this.bootstrapper.disableAutoApplicationStartupRegistration = true; + return this; + } + + /// + /// Disables automatic registration of user-defined instances. It + /// will not prevent auto-registration of implementations bundled with Nancy. + /// + /// A reference to the current . + public ConfigurableBootstrapperConfigurator DisableAutoRequestStartupRegistration() + { + this.bootstrapper.disableAutoRequestStartupRegistration = true; + return this; + } + + /// + /// Adds a hook to the application startup pipeline. This can be called multiple times to add + /// more hooks. + /// + /// The pipeline hook. + /// A reference to the current . public ConfigurableBootstrapperConfigurator ApplicationStartup(Action action) { this.bootstrapper.applicationStartupActions.Add(action); return this; } + /// + /// Adds a hook to the request startup pipeline. This can be called multiple times to add + /// more hooks. + /// + /// The pipeline hook. + /// A reference to the current . public ConfigurableBootstrapperConfigurator RequestStartup(Action action) { this.bootstrapper.requestStartupActions.Add(action); return this; } + /// + /// Disables registrations performed by instances. + /// + /// A reference to the current . public ConfigurableBootstrapperConfigurator DisableAutoRegistrations() { this.bootstrapper.autoRegistrations = false;