PageRenderTime 51ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 1ms

/src/Nancy.Testing/ConfigurableBootstrapper.cs

http://github.com/NancyFx/Nancy
C# | 2119 lines | 1065 code | 270 blank | 784 comment | 24 complexity | 597c068d7a6a4b8714f76067aae0a459 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-3.0, Apache-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. namespace Nancy.Testing
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Reflection;
  8. using Nancy.Bootstrapper;
  9. using Nancy.Configuration;
  10. using Nancy.Conventions;
  11. using Nancy.Culture;
  12. using Nancy.Diagnostics;
  13. using Nancy.ErrorHandling;
  14. using Nancy.Localization;
  15. using Nancy.ModelBinding;
  16. using Nancy.Responses.Negotiation;
  17. using Nancy.Routing;
  18. using Nancy.Routing.Constraints;
  19. using Nancy.Routing.Trie;
  20. using Nancy.Security;
  21. using Nancy.TinyIoc;
  22. using Nancy.Validation;
  23. using Nancy.ViewEngines;
  24. /// <summary>
  25. /// A Nancy bootstrapper that can be configured with either Type or Instance overrides for all Nancy types.
  26. /// </summary>
  27. public class ConfigurableBootstrapper : NancyBootstrapperWithRequestContainerBase<TinyIoCContainer>, IPipelines, INancyModuleCatalog
  28. {
  29. private readonly List<object> registeredTypes;
  30. private readonly List<InstanceRegistration> registeredInstances;
  31. private readonly NancyInternalConfiguration configuration;
  32. private readonly ConfigurableModuleCatalog catalog;
  33. private bool enableAutoRegistration;
  34. private readonly List<Action<TinyIoCContainer, IPipelines>> applicationStartupActions;
  35. private readonly List<Action<TinyIoCContainer, IPipelines, NancyContext>> requestStartupActions;
  36. private readonly Assembly nancyAssembly = typeof(NancyEngine).GetTypeInfo().Assembly;
  37. private Action<INancyEnvironment> configure;
  38. private readonly IList<Action<NancyInternalConfiguration>> configurationOverrides;
  39. /// <summary>
  40. /// Test project name suffixes that will be stripped from the test name project
  41. /// in order to try and resolve the name of the assembly that is under test so
  42. /// that all of its references can be loaded into the application domain.
  43. /// </summary>
  44. public static IList<string> TestAssemblySuffixes = new[] { "test", "tests", "unittests", "specs", "specifications" };
  45. private bool allDiscoveredModules;
  46. private bool autoRegistrations = true;
  47. private bool disableAutoApplicationStartupRegistration;
  48. private bool disableAutoRequestStartupRegistration;
  49. /// <summary>
  50. /// Initializes a new instance of the <see cref="ConfigurableBootstrapper"/> class.
  51. /// </summary>
  52. public ConfigurableBootstrapper()
  53. : this(null)
  54. {
  55. }
  56. /// <summary>
  57. /// Initializes a new instance of the <see cref="ConfigurableBootstrapper"/> class.
  58. /// </summary>
  59. /// <param name="configuration">The configuration that should be used by the bootstrapper.</param>
  60. public ConfigurableBootstrapper(Action<ConfigurableBootstrapperConfigurator> configuration)
  61. {
  62. this.catalog = new ConfigurableModuleCatalog();
  63. this.configuration = NancyInternalConfiguration.Default.Invoke(this.TypeCatalog);
  64. this.registeredTypes = new List<object>();
  65. this.registeredInstances = new List<InstanceRegistration>();
  66. this.applicationStartupActions = new List<Action<TinyIoCContainer, IPipelines>>();
  67. this.requestStartupActions = new List<Action<TinyIoCContainer, IPipelines, NancyContext>>();
  68. this.configurationOverrides = new List<Action<NancyInternalConfiguration>>();
  69. if (configuration != null)
  70. {
  71. var configurator =
  72. new ConfigurableBootstrapperConfigurator(this);
  73. configurator.StatusCodeHandler<PassThroughStatusCodeHandler>();
  74. configuration.Invoke(configurator);
  75. foreach (var configurationOverride in this.configurationOverrides)
  76. {
  77. configurationOverride.Invoke(this.configuration);
  78. }
  79. }
  80. }
  81. /// <summary>
  82. /// Configures the Nancy environment
  83. /// </summary>
  84. /// <param name="environment">The <see cref="INancyEnvironment"/> instance to configure</param>
  85. public override void Configure(INancyEnvironment environment)
  86. {
  87. if (this.configure != null)
  88. {
  89. this.configure.Invoke(environment);
  90. }
  91. }
  92. /// <summary>
  93. /// Initialise the bootstrapper - can be used for adding pre/post hooks and
  94. /// any other initialisation tasks that aren't specifically container setup
  95. /// related
  96. /// </summary>
  97. /// <param name="container">Container instance for resolving types if required.</param>
  98. protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
  99. {
  100. base.ApplicationStartup(container, pipelines);
  101. foreach (var action in this.applicationStartupActions)
  102. {
  103. action.Invoke(container, pipelines);
  104. }
  105. }
  106. /// <summary>
  107. /// Initialise the request - can be used for adding pre/post hooks and
  108. /// any other per-request initialisation tasks that aren't specifically container setup
  109. /// related
  110. /// </summary>
  111. /// <param name="container">Container</param>
  112. /// <param name="pipelines">Current pipelines</param>
  113. /// <param name="context">Current context</param>
  114. protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
  115. {
  116. base.RequestStartup(container, pipelines, context);
  117. foreach (var action in this.requestStartupActions)
  118. {
  119. action.Invoke(container, pipelines, context);
  120. }
  121. }
  122. /// <summary>
  123. /// Get all NancyModule implementation instances
  124. /// </summary>
  125. /// <param name="context">The current context</param>
  126. /// <returns>An <see cref="IEnumerable{T}"/> instance containing <see cref="INancyModule"/> instances.</returns>
  127. public new IEnumerable<INancyModule> GetAllModules(NancyContext context)
  128. {
  129. return base.GetAllModules(context).Union(this.catalog.GetAllModules(context));
  130. }
  131. /// <summary>
  132. /// Get the <see cref="INancyEnvironment"/> instance.
  133. /// </summary>
  134. /// <returns>An configured <see cref="INancyEnvironment"/> instance.</returns>
  135. /// <remarks>The boostrapper must be initialised (<see cref="INancyBootstrapper.Initialise"/>) prior to calling this.</remarks>
  136. public override INancyEnvironment GetEnvironment()
  137. {
  138. return base.ApplicationContainer.Resolve<INancyEnvironment>();
  139. }
  140. /// <summary>
  141. /// Retrieve a specific module instance from the container
  142. /// </summary>
  143. /// <param name="container">Container to use</param>
  144. /// <param name="moduleType">Type of the module</param>
  145. /// <returns>INancyModule instance</returns>
  146. protected override INancyModule GetModule(TinyIoCContainer container, Type moduleType)
  147. {
  148. var module =
  149. this.catalog.GetModule(moduleType, null);
  150. if (module != null)
  151. {
  152. return module;
  153. }
  154. container.Register(typeof(INancyModule), moduleType);
  155. return container.Resolve<INancyModule>();
  156. }
  157. private IEnumerable<ModuleRegistration> GetModuleRegistrations()
  158. {
  159. return this.registeredTypes.Where(x => x is ModuleRegistration).Cast<ModuleRegistration>();
  160. }
  161. private IEnumerable<TypeRegistration> GetTypeRegistrations()
  162. {
  163. return this.registeredTypes.Where(x => x is TypeRegistration).Cast<TypeRegistration>();
  164. }
  165. private IEnumerable<CollectionTypeRegistration> GetCollectionTypeRegistrations()
  166. {
  167. return this.registeredTypes.Where(x => x.GetType() == typeof(CollectionTypeRegistration)).Cast<CollectionTypeRegistration>();
  168. }
  169. private static string GetSafePathExtension(string name)
  170. {
  171. return Path.GetExtension(name) ?? string.Empty;
  172. }
  173. private IEnumerable<Type> Resolve<T>()
  174. {
  175. var types = this.GetTypeRegistrations()
  176. .Where(x => x.RegistrationType == typeof(T))
  177. .Select(x => x.ImplementationType)
  178. .ToList();
  179. return (types.Any()) ? types : null;
  180. }
  181. /// <summary>
  182. /// Nancy internal configuration
  183. /// </summary>
  184. protected override sealed Func<ITypeCatalog, NancyInternalConfiguration> InternalConfiguration
  185. {
  186. get { return x => this.configuration; }
  187. }
  188. /// <summary>
  189. /// Nancy conventions
  190. /// </summary>
  191. protected override NancyConventions Conventions
  192. {
  193. get
  194. {
  195. var conventions = this.registeredInstances
  196. .Where(x => x.RegistrationType == typeof(NancyConventions))
  197. .Select(x => x.Implementation)
  198. .Cast<NancyConventions>()
  199. .FirstOrDefault();
  200. return conventions ?? base.Conventions;
  201. }
  202. }
  203. /// <summary>
  204. /// Gets all available module types
  205. /// </summary>
  206. protected override IEnumerable<ModuleRegistration> Modules
  207. {
  208. get
  209. {
  210. var moduleRegistrations =
  211. this.GetModuleRegistrations().ToList();
  212. if (moduleRegistrations.Any())
  213. {
  214. return moduleRegistrations;
  215. }
  216. return this.allDiscoveredModules ? base.Modules : ArrayCache.Empty<ModuleRegistration>();
  217. }
  218. }
  219. /// <summary>
  220. /// Gets the available view engine types
  221. /// </summary>
  222. protected override IEnumerable<Type> ViewEngines
  223. {
  224. get { return this.Resolve<IViewEngine>() ?? base.ViewEngines; }
  225. }
  226. /// <summary>
  227. /// Gets the available custom model binders
  228. /// </summary>
  229. protected override IEnumerable<Type> ModelBinders
  230. {
  231. get { return this.Resolve<IModelBinder>() ?? base.ModelBinders; }
  232. }
  233. /// <summary>
  234. /// Gets the available custom type converters
  235. /// </summary>
  236. protected override IEnumerable<Type> TypeConverters
  237. {
  238. get { return this.Resolve<ITypeConverter>() ?? base.TypeConverters; }
  239. }
  240. /// <summary>
  241. /// Gets the available custom body deserializers
  242. /// </summary>
  243. protected override IEnumerable<Type> BodyDeserializers
  244. {
  245. get { return this.Resolve<IBodyDeserializer>() ?? base.BodyDeserializers; }
  246. }
  247. /// <summary>
  248. /// Gets all startup tasks
  249. /// </summary>
  250. protected override IEnumerable<Type> ApplicationStartupTasks
  251. {
  252. get
  253. {
  254. var tasks = base.ApplicationStartupTasks;
  255. var user = (this.Resolve<IApplicationStartup>() ?? Enumerable.Empty<Type>()).ToArray();
  256. if (this.disableAutoApplicationStartupRegistration || user.Any())
  257. {
  258. tasks = tasks.Where(x => x.GetTypeInfo().Assembly.GetName().Name.StartsWith("Nancy", StringComparison.OrdinalIgnoreCase));
  259. }
  260. return tasks.Union(user);
  261. }
  262. }
  263. /// <summary>
  264. /// Gets all request startup tasks
  265. /// </summary>
  266. protected override IEnumerable<Type> RequestStartupTasks
  267. {
  268. get
  269. {
  270. var tasks = base.RequestStartupTasks;
  271. var user = (this.Resolve<IRequestStartup>() ?? Enumerable.Empty<Type>()).ToArray();
  272. if (this.disableAutoRequestStartupRegistration || user.Any())
  273. {
  274. tasks = tasks.Where(x => x.GetTypeInfo().Assembly.GetName().Name.StartsWith("Nancy", StringComparison.OrdinalIgnoreCase));
  275. }
  276. return tasks.Union(user);
  277. }
  278. }
  279. /// <summary>
  280. /// Gets the root path provider
  281. /// </summary>
  282. protected override IRootPathProvider RootPathProvider
  283. {
  284. get { return new DefaultRootPathProvider(); }
  285. }
  286. /// <summary>
  287. /// Configures the container using AutoRegister followed by registration
  288. /// of default INancyModuleCatalog and IRouteResolver.
  289. /// </summary>
  290. /// <param name="container">Container instance</param>
  291. protected override void ConfigureApplicationContainer(TinyIoCContainer container)
  292. {
  293. if (this.enableAutoRegistration)
  294. {
  295. container.AutoRegister();
  296. this.RegisterBootstrapperTypes(container);
  297. }
  298. RegisterTypesInternal(this.ApplicationContainer, this.GetTypeRegistrations());
  299. RegisterCollectionTypesInternal(this.ApplicationContainer, this.GetCollectionTypeRegistrations());
  300. RegisterInstancesInternal(this.ApplicationContainer, this.registeredInstances);
  301. }
  302. /// <summary>
  303. /// Creates a per request child/nested container
  304. /// </summary>
  305. /// <param name="context">Current context</param>
  306. /// <returns>Request container instance</returns>
  307. protected override TinyIoCContainer CreateRequestContainer(NancyContext context)
  308. {
  309. return this.ApplicationContainer.GetChildContainer();
  310. }
  311. /// <summary>
  312. /// Retrieve all module instances from the container
  313. /// </summary>
  314. /// <param name="container">Container to use</param>
  315. /// <returns>Collection of INancyModule instances</returns>
  316. protected override IEnumerable<INancyModule> GetAllModules(TinyIoCContainer container)
  317. {
  318. return container.ResolveAll<INancyModule>(false);
  319. }
  320. /// <summary>
  321. /// Gets the application level container
  322. /// </summary>
  323. /// <returns>Container instance</returns>
  324. protected override TinyIoCContainer GetApplicationContainer()
  325. {
  326. return new TinyIoCContainer();
  327. }
  328. /// <summary>
  329. /// Resolve INancyEngine
  330. /// </summary>
  331. /// <returns>INancyEngine implementation</returns>
  332. protected override INancyEngine GetEngineInternal()
  333. {
  334. try
  335. {
  336. return this.ApplicationContainer.Resolve<INancyEngine>();
  337. }
  338. catch (InvalidOperationException ex)
  339. {
  340. throw new InvalidOperationException(
  341. "Something went wrong when trying to satisfy one of the dependencies during composition, make sure that you've registered all new dependencies in the container and specified either a module to test, or set AllDiscoveredModules in the ConfigurableBootstrapper. Inspect the innerexception for more details.",
  342. ex.InnerException);
  343. }
  344. }
  345. /// <summary>
  346. /// Gets the diagnostics for initialization
  347. /// </summary>
  348. /// <returns>IDiagnostics implementation</returns>
  349. protected override IDiagnostics GetDiagnostics()
  350. {
  351. return this.ApplicationContainer.Resolve<IDiagnostics>();
  352. }
  353. /// <summary>
  354. /// Gets all registered startup tasks
  355. /// </summary>
  356. /// <returns>An <see cref="IEnumerable{T}"/> instance containing <see cref="IApplicationStartup"/> instances. </returns>
  357. protected override IEnumerable<IApplicationStartup> GetApplicationStartupTasks()
  358. {
  359. return this.ApplicationContainer.ResolveAll<IApplicationStartup>(false);
  360. }
  361. /// <summary>
  362. /// Gets all registered request startup tasks
  363. /// </summary>
  364. /// <returns>An <see cref="System.Collections.Generic.IEnumerable{T}"/> instance containing <see cref="IRequestStartup"/> instances.</returns>
  365. protected override IEnumerable<IRequestStartup> RegisterAndGetRequestStartupTasks(TinyIoCContainer container, Type[] requestStartupTypes)
  366. {
  367. container.RegisterMultiple(typeof(IRequestStartup), requestStartupTypes);
  368. return container.ResolveAll<IRequestStartup>(false);
  369. }
  370. /// <summary>
  371. /// Gets all registered application registration tasks
  372. /// </summary>
  373. /// <returns>An <see cref="IEnumerable{T}"/> instance containing <see cref="IRegistrations"/> instances.</returns>
  374. protected override IEnumerable<IRegistrations> GetRegistrationTasks()
  375. {
  376. if (this.autoRegistrations)
  377. {
  378. return this.ApplicationContainer.ResolveAll<IRegistrations>(false);
  379. }
  380. return this.ApplicationContainer.ResolveAll<IRegistrations>(false)
  381. .Where(x => x.GetType().GetTypeInfo().Assembly == nancyAssembly);
  382. }
  383. /// <summary>
  384. /// Register the bootstrapper's implemented types into the container.
  385. /// This is necessary so a user can pass in a populated container but not have
  386. /// to take the responsibility of registering things like INancyModuleCatalog manually.
  387. /// </summary>
  388. /// <param name="applicationContainer">Application container to register into</param>
  389. protected override void RegisterBootstrapperTypes(TinyIoCContainer applicationContainer)
  390. {
  391. var moduleCatalog = this.registeredInstances
  392. .Where(x => x.RegistrationType == typeof(INancyModuleCatalog))
  393. .Select(x => x.Implementation)
  394. .Cast<INancyModuleCatalog>()
  395. .FirstOrDefault() ?? this;
  396. applicationContainer.Register<INancyModuleCatalog>(moduleCatalog);
  397. }
  398. /// <summary>
  399. /// Register the default implementations of internally used types into the container as singletons
  400. /// </summary>
  401. /// <param name="container">Container to register into</param>
  402. /// <param name="typeRegistrations">Type registrations to register</param>
  403. protected override void RegisterTypes(TinyIoCContainer container, IEnumerable<TypeRegistration> typeRegistrations)
  404. {
  405. var configuredTypes =
  406. this.GetTypeRegistrations().ToList();
  407. var filtered = typeRegistrations
  408. .Where(x => !configuredTypes.Any(y => y.RegistrationType == x.RegistrationType))
  409. .Where(x => !this.registeredInstances.Any(y => y.RegistrationType == x.RegistrationType));
  410. RegisterTypesInternal(container, filtered);
  411. }
  412. private static void RegisterTypesInternal(TinyIoCContainer container, IEnumerable<TypeRegistration> filtered)
  413. {
  414. foreach (var typeRegistration in filtered)
  415. {
  416. container.Register(typeRegistration.RegistrationType, typeRegistration.ImplementationType).AsSingleton();
  417. }
  418. }
  419. /// <summary>
  420. /// Register the various collections into the container as singletons to later be resolved
  421. /// by IEnumerable{Type} constructor dependencies.
  422. /// </summary>
  423. /// <param name="container">Container to register into</param>
  424. /// <param name="collectionTypeRegistrations">Collection type registrations to register</param>
  425. protected override void RegisterCollectionTypes(TinyIoCContainer container, IEnumerable<CollectionTypeRegistration> collectionTypeRegistrations)
  426. {
  427. var configuredCollectionTypes =
  428. this.GetCollectionTypeRegistrations().ToList();
  429. var filtered = collectionTypeRegistrations
  430. .Where(x => !configuredCollectionTypes.Any(y => y.RegistrationType == x.RegistrationType));
  431. RegisterCollectionTypesInternal(container, filtered);
  432. }
  433. private static void RegisterCollectionTypesInternal(TinyIoCContainer container, IEnumerable<CollectionTypeRegistration> filtered)
  434. {
  435. foreach (var collectionTypeRegistration in filtered)
  436. {
  437. container.RegisterMultiple(collectionTypeRegistration.RegistrationType,
  438. collectionTypeRegistration.ImplementationTypes);
  439. }
  440. }
  441. /// <summary>
  442. /// Register the given instances into the container
  443. /// </summary>
  444. /// <param name="container">Container to register into</param>
  445. /// <param name="instanceRegistrations">Instance registration types</param>
  446. protected override void RegisterInstances(TinyIoCContainer container, IEnumerable<InstanceRegistration> instanceRegistrations)
  447. {
  448. var configuredInstanceRegistrations = this.GetTypeRegistrations();
  449. var fileteredInstanceRegistrations = instanceRegistrations
  450. .Where(x => !this.registeredInstances.Any(y => y.RegistrationType == x.RegistrationType))
  451. .Where(x => !configuredInstanceRegistrations.Any(y => y.RegistrationType == x.RegistrationType))
  452. .ToList();
  453. RegisterInstancesInternal(container, fileteredInstanceRegistrations);
  454. }
  455. private static void RegisterInstancesInternal(TinyIoCContainer container, IEnumerable<InstanceRegistration> fileteredInstanceRegistrations)
  456. {
  457. foreach (var instanceRegistration in fileteredInstanceRegistrations)
  458. {
  459. container.Register(
  460. instanceRegistration.RegistrationType,
  461. instanceRegistration.Implementation);
  462. }
  463. }
  464. /// <summary>
  465. /// Register the given module types into the request container
  466. /// </summary>
  467. /// <param name="container">Container to register into</param>
  468. /// <param name="moduleRegistrationTypes">NancyModule types</param>
  469. protected override void RegisterRequestContainerModules(TinyIoCContainer container, IEnumerable<ModuleRegistration> moduleRegistrationTypes)
  470. {
  471. foreach (var moduleRegistrationType in moduleRegistrationTypes)
  472. {
  473. container.Register(
  474. typeof(INancyModule),
  475. moduleRegistrationType.ModuleType,
  476. moduleRegistrationType.ModuleType.FullName).
  477. AsSingleton();
  478. }
  479. }
  480. /// <summary>
  481. /// Gets the <see cref="INancyEnvironmentConfigurator"/> used by th.
  482. /// </summary>
  483. /// <returns>An <see cref="INancyEnvironmentConfigurator"/> instance.</returns>
  484. protected override INancyEnvironmentConfigurator GetEnvironmentConfigurator()
  485. {
  486. return this.ApplicationContainer.Resolve<INancyEnvironmentConfigurator>();
  487. }
  488. /// <summary>
  489. /// Registers an <see cref="INancyEnvironment"/> instance in the container.
  490. /// </summary>
  491. /// <param name="container">The container to register into.</param>
  492. /// <param name="environment">The <see cref="INancyEnvironment"/> instance to register.</param>
  493. protected override void RegisterNancyEnvironment(TinyIoCContainer container, INancyEnvironment environment)
  494. {
  495. container.Register(environment);
  496. }
  497. /// <summary>
  498. /// <para>
  499. /// The pre-request hook
  500. /// </para>
  501. /// <para>
  502. /// The PreRequest hook is called prior to processing a request. If a hook returns
  503. /// a non-null response then processing is aborted and the response provided is
  504. /// returned.
  505. /// </para>
  506. /// </summary>
  507. public BeforePipeline BeforeRequest
  508. {
  509. get { return this.ApplicationPipelines.BeforeRequest; }
  510. set { this.ApplicationPipelines.BeforeRequest = value; }
  511. }
  512. /// <summary>
  513. /// <para>
  514. /// The post-request hook
  515. /// </para>
  516. /// <para>
  517. /// The post-request hook is called after the response is created. It can be used
  518. /// to rewrite the response or add/remove items from the context.
  519. /// </para>
  520. /// </summary>
  521. public AfterPipeline AfterRequest
  522. {
  523. get { return this.ApplicationPipelines.AfterRequest; }
  524. set { this.ApplicationPipelines.AfterRequest = value; }
  525. }
  526. /// <summary>
  527. /// <para>
  528. /// The error hook
  529. /// </para>
  530. /// <para>
  531. /// The error hook is called if an exception is thrown at any time during the pipeline.
  532. /// If no error hook exists a standard InternalServerError response is returned
  533. /// </para>
  534. /// </summary>
  535. public ErrorPipeline OnError
  536. {
  537. get { return this.ApplicationPipelines.OnError; }
  538. set { this.ApplicationPipelines.OnError = value; }
  539. }
  540. /// <summary>
  541. /// Provides an API for configuring a <see cref="ConfigurableBootstrapper"/> instance.
  542. /// </summary>
  543. public class ConfigurableBootstrapperConfigurator
  544. {
  545. private readonly ConfigurableBootstrapper bootstrapper;
  546. /// <summary>
  547. /// Initializes a new instance of the <see cref="ConfigurableBootstrapperConfigurator"/> class.
  548. /// </summary>
  549. /// <param name="bootstrapper">The bootstrapper that should be configured.</param>
  550. public ConfigurableBootstrapperConfigurator(ConfigurableBootstrapper bootstrapper)
  551. {
  552. this.bootstrapper = bootstrapper;
  553. this.Diagnostics<DisabledDiagnostics>();
  554. }
  555. public ConfigurableBootstrapperConfigurator AllDiscoveredModules()
  556. {
  557. this.bootstrapper.allDiscoveredModules = true;
  558. return this;
  559. }
  560. public ConfigurableBootstrapperConfigurator Binder(IBinder binder)
  561. {
  562. this.bootstrapper.registeredInstances.Add(
  563. new InstanceRegistration(typeof(IBinder), binder));
  564. return this;
  565. }
  566. /// <summary>
  567. /// Configures the bootstrapper to create an <see cref="IBinder"/> instance of the specified type.
  568. /// </summary>
  569. /// <typeparam name="T">The type of the <see cref="IBinder"/> that the bootstrapper should use.</typeparam>
  570. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  571. public ConfigurableBootstrapperConfigurator Binder<T>() where T : IBinder
  572. {
  573. this.bootstrapper.configurationOverrides.Add(x => x.Binder = typeof(T));
  574. return this;
  575. }
  576. /// <summary>
  577. /// Configures the <see cref="INancyEnvironment"/>.
  578. /// </summary>
  579. /// <param name="configuration">The configuration to apply to the environment.</param>
  580. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  581. public ConfigurableBootstrapperConfigurator Configure(Action<INancyEnvironment> configuration)
  582. {
  583. this.bootstrapper.configure = configuration;
  584. return this;
  585. }
  586. /// <summary>
  587. /// Configures the bootstrapper to use the provided instance of <see cref="INancyContextFactory"/>.
  588. /// </summary>
  589. /// <param name="contextFactory">The <see cref="INancyContextFactory"/> instance that should be used by the bootstrapper.</param>
  590. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  591. public ConfigurableBootstrapperConfigurator ContextFactory(INancyContextFactory contextFactory)
  592. {
  593. this.bootstrapper.registeredInstances.Add(
  594. new InstanceRegistration(typeof(INancyContextFactory), contextFactory));
  595. return this;
  596. }
  597. /// <summary>
  598. /// Configures the bootstrapper to create an <see cref="INancyContextFactory"/> instance of the specified type.
  599. /// </summary>
  600. /// <typeparam name="T">The type of the <see cref="INancyContextFactory"/> that the bootstrapper should use.</typeparam>
  601. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  602. public ConfigurableBootstrapperConfigurator ContextFactory<T>() where T : INancyContextFactory
  603. {
  604. this.bootstrapper.configurationOverrides.Add(x => x.ContextFactory = typeof(T));
  605. return this;
  606. }
  607. /// <summary>
  608. /// Configures the bootstrapper to create an <see cref="INancyDefaultConfigurationProvider"/> instance of the specified type.
  609. /// </summary>
  610. /// <typeparam name="T">The type of the <see cref="IRouteMetadataProvider"/> that the bootstrapper should use.</typeparam>
  611. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  612. public ConfigurableBootstrapperConfigurator DefaultConfigurationProvider<T>() where T : INancyDefaultConfigurationProvider
  613. {
  614. this.bootstrapper.configurationOverrides.Add(x => x.DefaultConfigurationProviders = new List<Type>(new[] { typeof(T) }));
  615. return this;
  616. }
  617. /// <summary>
  618. /// Configures the bootstrapper to use the provided <see cref="INancyDefaultConfigurationProvider"/> types.
  619. /// </summary>
  620. /// <param name="defaultConfigurationProviders">The <see cref="INancyDefaultConfigurationProvider"/> types that should be used by the bootstrapper.</param>
  621. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  622. public ConfigurableBootstrapperConfigurator DefaultConfigurationProviders(params Type[] defaultConfigurationProviders)
  623. {
  624. this.bootstrapper.configurationOverrides.Add(x => x.DefaultConfigurationProviders = defaultConfigurationProviders);
  625. return this;
  626. }
  627. /// <summary>
  628. /// Configures the bootstrapper to use the provided instances of <see cref="INancyDefaultConfigurationProvider"/>.
  629. /// </summary>
  630. /// <param name="defaultConfigurationProvider">The <see cref="INancyDefaultConfigurationProvider"/> types that should be used by the bootstrapper.</param>
  631. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  632. public ConfigurableBootstrapperConfigurator DefaultConfigurationProviders(INancyDefaultConfigurationProvider defaultConfigurationProvider)
  633. {
  634. this.bootstrapper.registeredInstances.Add(
  635. new InstanceRegistration(typeof(INancyDefaultConfigurationProvider), defaultConfigurationProvider));
  636. return this;
  637. }
  638. /// <summary>
  639. /// Configures the bootstrapper to use the provided instances of <see cref="INancyDefaultConfigurationProvider"/>.
  640. /// </summary>
  641. /// <param name="defaultConfigurationProviders">The <see cref="INancyDefaultConfigurationProvider"/> types that should be used by the bootstrapper.</param>
  642. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  643. public ConfigurableBootstrapperConfigurator DefaultConfigurationProviders(params INancyDefaultConfigurationProvider[] defaultConfigurationProviders)
  644. {
  645. foreach (var defaultConfigurationProvider in defaultConfigurationProviders)
  646. {
  647. this.bootstrapper.registeredInstances.Add(
  648. new InstanceRegistration(typeof(INancyDefaultConfigurationProvider), defaultConfigurationProvider));
  649. }
  650. return this;
  651. }
  652. /// <summary>
  653. /// Configures the bootstrapper to use the provided type as a dependency.
  654. /// </summary>
  655. /// <param name="type">The type of the dependency that should be used registered with the bootstrapper.</param>
  656. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  657. public ConfigurableBootstrapperConfigurator Dependency<T>(Type type)
  658. {
  659. this.bootstrapper.registeredTypes.Add(new TypeRegistration(typeof(T), type));
  660. return this;
  661. }
  662. /// <summary>
  663. /// Configures the bootstrapper to register the specified type as a dependency.
  664. /// </summary>
  665. /// <typeparam name="T">The type of the dependency that should be registered with the bootstrapper.</typeparam>
  666. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  667. /// <remarks>This method will register the type for all the interfaces it implements and the type itself.</remarks>
  668. public ConfigurableBootstrapperConfigurator Dependency<T>()
  669. {
  670. this.bootstrapper.registeredTypes.Add(new TypeRegistration(typeof(T), typeof(T)));
  671. foreach (var interfaceType in GetSafeInterfaces(typeof(T)))
  672. {
  673. this.bootstrapper.registeredTypes.Add(new TypeRegistration(interfaceType, typeof(T)));
  674. }
  675. return this;
  676. }
  677. /// <summary>
  678. /// Configures the bootstrapper to use the provided instance as a dependency.
  679. /// </summary>
  680. /// <param name="instance">The dependency instance that should be used registered with the bootstrapper.</param>
  681. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  682. /// <remarks>This method will register the instance for all the interfaces it implements and the type itself.</remarks>
  683. public ConfigurableBootstrapperConfigurator Dependency<T>(T instance)
  684. {
  685. this.bootstrapper.registeredInstances.Add(new InstanceRegistration(typeof(T), instance));
  686. var interfacesToRegisterBy = GetSafeInterfaces(instance.GetType()).Where(i => !i.Equals(typeof(T)));
  687. foreach (var interfaceType in interfacesToRegisterBy)
  688. {
  689. this.bootstrapper.registeredInstances.Add(new InstanceRegistration(interfaceType, instance));
  690. }
  691. return this;
  692. }
  693. private static IEnumerable<Type> GetSafeInterfaces(Type type)
  694. {
  695. return type.GetInterfaces().Where(x => x != typeof(IDisposable));
  696. }
  697. /// <summary>
  698. /// Configures the bootstrapper to register the specified types and instances as a dependencies.
  699. /// </summary>
  700. /// <param name="dependencies">An array of maps between the interfaces and instances that should be registered with the bootstrapper.</param>
  701. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  702. public ConfigurableBootstrapperConfigurator MappedDependencies<T, K>(IEnumerable<Tuple<T, K>> dependencies)
  703. where T : Type
  704. where K : class
  705. {
  706. foreach (var dependency in dependencies)
  707. {
  708. this.bootstrapper.registeredInstances.Add(
  709. new InstanceRegistration(dependency.Item1, dependency.Item2));
  710. }
  711. return this;
  712. }
  713. /// <summary>
  714. /// Configures the bootstrapper to register the specified instances as a dependencies.
  715. /// </summary>
  716. /// <param name="dependencies">The instances of the dependencies that should be registered with the bootstrapper.</param>
  717. /// <typeparam name="T">The type that the dependencies should be registered as.</typeparam>
  718. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  719. public ConfigurableBootstrapperConfigurator Dependencies<T>(params T[] dependencies)
  720. {
  721. foreach (var dependency in dependencies)
  722. {
  723. this.Dependency(dependency);
  724. }
  725. return this;
  726. }
  727. /// <summary>
  728. /// Configures the bootstrapper to use the provided types as a dependency.
  729. /// </summary>
  730. /// <param name="dependencies">The types that should be used registered as dependencies with the bootstrapper.</param>
  731. /// <typeparam name="T">The type that the dependencies should be registered as.</typeparam>
  732. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  733. public ConfigurableBootstrapperConfigurator Dependencies<T>(params Type[] dependencies)
  734. {
  735. foreach (var dependency in dependencies)
  736. {
  737. this.Dependency<T>(dependency);
  738. }
  739. return this;
  740. }
  741. /// <summary>
  742. /// Enables the auto registration behavior of the bootstrapper
  743. /// </summary>
  744. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  745. public ConfigurableBootstrapperConfigurator EnableAutoRegistration()
  746. {
  747. this.bootstrapper.enableAutoRegistration = true;
  748. return this;
  749. }
  750. /// <summary>
  751. /// Configures the bootstrapper to use the provided instance of <see cref="IStatusCodeHandler"/>.
  752. /// </summary>
  753. /// <param name="statusCodeHandlers">The <see cref="IStatusCodeHandler"/> types that should be used by the bootstrapper.</param>
  754. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  755. public ConfigurableBootstrapperConfigurator StatusCodeHandlers(params Type[] statusCodeHandlers)
  756. {
  757. this.bootstrapper.configurationOverrides.Add(x => x.StatusCodeHandlers = new List<Type>(statusCodeHandlers));
  758. return this;
  759. }
  760. /// <summary>
  761. /// Configures the bootstrapper to create an <see cref="IStatusCodeHandler"/> instance of the specified type.
  762. /// </summary>
  763. /// <typeparam name="T">The type of the <see cref="IStatusCodeHandler"/> that the bootstrapper should use.</typeparam>
  764. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  765. public ConfigurableBootstrapperConfigurator StatusCodeHandler<T>() where T : IStatusCodeHandler
  766. {
  767. this.bootstrapper.configurationOverrides.Add(x => x.StatusCodeHandlers = new List<Type>(new[] { typeof(T) }));
  768. return this;
  769. }
  770. /// <summary>
  771. /// Configures the bootstrapper to create an <see cref="INancyEnvironmentConfigurator"/> instance of the specified type.
  772. /// </summary>
  773. /// <typeparam name="T">The type of the <see cref="INancyEnvironmentConfigurator"/> that the bootstrapper should use.</typeparam>
  774. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  775. public ConfigurableBootstrapperConfigurator EnvironmentConfigurator<T>() where T : INancyEnvironmentConfigurator
  776. {
  777. this.bootstrapper.configurationOverrides.Add(x => x.EnvironmentConfigurator = typeof(T));
  778. return this;
  779. }
  780. /// <summary>
  781. /// Configures the bootstrapper to use the provided instance of <see cref="INancyEnvironmentConfigurator"/>.
  782. /// </summary>
  783. /// <param name="environmentConfigurator">The <see cref="INancyEnvironmentConfigurator"/> instance that should be used by the bootstrapper.</param>
  784. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  785. public ConfigurableBootstrapperConfigurator EnvironmentConfigurator(INancyEnvironmentConfigurator environmentConfigurator)
  786. {
  787. this.bootstrapper.registeredInstances.Add(
  788. new InstanceRegistration(typeof(INancyEnvironmentConfigurator), environmentConfigurator));
  789. return this;
  790. }
  791. /// <summary>
  792. /// Configures the bootstrapper to use the provided instance of <see cref="INancyEnvironmentFactory"/>.
  793. /// </summary>
  794. /// <param name="environmentFactory">The <see cref="INancyEnvironmentFactory"/> instance that should be used by the bootstrapper.</param>
  795. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  796. public ConfigurableBootstrapperConfigurator EnvironmentFactory(INancyEnvironmentFactory environmentFactory)
  797. {
  798. this.bootstrapper.registeredInstances.Add(
  799. new InstanceRegistration(typeof(INancyEnvironmentConfigurator), environmentFactory));
  800. return this;
  801. }
  802. /// <summary>
  803. /// Configures the bootstrapper to create an <see cref="INancyEnvironmentFactory"/> instance of the specified type.
  804. /// </summary>
  805. /// <typeparam name="T">The type of the <see cref="INancyEnvironmentFactory"/> that the bootstrapper should use.</typeparam>
  806. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  807. public ConfigurableBootstrapperConfigurator EnvironmentFactory<T>() where T : INancyEnvironmentFactory
  808. {
  809. this.bootstrapper.configurationOverrides.Add(x => x.EnvironmentFactory = typeof(T));
  810. return this;
  811. }
  812. /// <summary>
  813. /// Configures the bootstrapper to use the provided instance of <see cref="IFieldNameConverter"/>.
  814. /// </summary>
  815. /// <param name="fieldNameConverter">The <see cref="IFieldNameConverter"/> instance that should be used by the bootstrapper.</param>
  816. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  817. public ConfigurableBootstrapperConfigurator FieldNameConverter(IFieldNameConverter fieldNameConverter)
  818. {
  819. this.bootstrapper.registeredInstances.Add(
  820. new InstanceRegistration(typeof(IFieldNameConverter), fieldNameConverter));
  821. return this;
  822. }
  823. /// <summary>
  824. /// Configures the bootstrapper to create an <see cref="IFieldNameConverter"/> instance of the specified type.
  825. /// </summary>
  826. /// <typeparam name="T">The type of the <see cref="IFieldNameConverter"/> that the bootstrapper should use.</typeparam>
  827. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  828. public ConfigurableBootstrapperConfigurator FieldNameConverter<T>() where T : IFieldNameConverter
  829. {
  830. this.bootstrapper.configurationOverrides.Add(x => x.FieldNameConverter = typeof(T));
  831. return this;
  832. }
  833. /// <summary>
  834. /// Configures the bootstrapper to use the provided instance of <see cref="IModelBinderLocator"/>.
  835. /// </summary>
  836. /// <param name="modelBinderLocator">The <see cref="IModelBinderLocator"/> instance that should be used by the bootstrapper.</param>
  837. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  838. public ConfigurableBootstrapperConfigurator ModelBinderLocator(IModelBinderLocator modelBinderLocator)
  839. {
  840. this.bootstrapper.registeredInstances.Add(
  841. new InstanceRegistration(typeof(IModelBinderLocator), modelBinderLocator));
  842. return this;
  843. }
  844. /// <summary>
  845. /// Configures the bootstrapper to create an <see cref="IModelBinderLocator"/> instance of the specified type.
  846. /// </summary>
  847. /// <typeparam name="T">The type of the <see cref="IModelBinderLocator"/> that the bootstrapper should use.</typeparam>
  848. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  849. public ConfigurableBootstrapperConfigurator ModelBinderLocator<T>() where T : IModelBinderLocator
  850. {
  851. this.bootstrapper.configurationOverrides.Add(x => x.ModelBinderLocator = typeof(T));
  852. return this;
  853. }
  854. /// <summary>
  855. /// Configures the bootstrapper to create a <see cref="INancyModule"/> instance of the specified type.
  856. /// </summary>
  857. /// <typeparam name="T">The type of the <see cref="INancyModule"/> that the bootstrapper should use.</typeparam>
  858. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  859. public ConfigurableBootstrapperConfigurator Module<T>() where T : INancyModule
  860. {
  861. return this.Modules(typeof(T));
  862. }
  863. /// <summary>
  864. /// Configures the bootstrapper to register the provided <see cref="INancyModule"/> instance.
  865. /// </summary>
  866. /// <param name="module">The <see cref="INancyModule"/> instance to register.</param>
  867. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  868. public ConfigurableBootstrapperConfigurator Module(INancyModule module)
  869. {
  870. this.bootstrapper.catalog.RegisterModuleInstance(module);
  871. return this;
  872. }
  873. /// <summary>
  874. /// Configures the bootstrapper to create <see cref="INancyModule"/> instances of the specified types.
  875. /// </summary>
  876. /// <param name="modules">The types of the <see cref="INancyModule"/> that the bootstrapper should use.</param>
  877. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  878. public ConfigurableBootstrapperConfigurator Modules(params Type[] modules)
  879. {
  880. var moduleRegistrations =
  881. from module in modules
  882. select new ModuleRegistration(module);
  883. this.bootstrapper.registeredTypes.AddRange(moduleRegistrations);
  884. return this;
  885. }
  886. /// <summary>
  887. /// Configures the bootstrapper to use the provided instance of <see cref="INancyEngine"/>.
  888. /// </summary>
  889. /// <param name="engine">The <see cref="INancyEngine"/> instance that should be used by the bootstrapper.</param>
  890. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  891. public ConfigurableBootstrapperConfigurator NancyEngine(INancyEngine engine)
  892. {
  893. this.bootstrapper.registeredInstances.Add(
  894. new InstanceRegistration(typeof(INancyEngine), engine));
  895. return this;
  896. }
  897. /// <summary>
  898. /// Configures the bootstrapper to create an <see cref="INancyEngine"/> instance of the specified type.
  899. /// </summary>
  900. /// <typeparam name="T">The type of the <see cref="INancyEngine"/> that the bootstrapper should use.</typeparam>
  901. /// <returns>A reference to the current <see cref="ConfigurableBootstrapperConfigurator"/>.</returns>
  902. public ConfigurableBootstrapperConfigurator NancyEngine<T>() where T : INancyEngine
  903. {
  904. this.bootstrapper.configurationOverrides.Add(x => x.NancyEngine = typeof(T));
  905. return this;
  906. }
  907. /// <summary>
  908. /// Configures the bootstrapper to use the provided instance of <see cref="INancyModuleBuilder…

Large files files are truncated, but you can click here to view the full file