diff --git a/src/Http/CrazyStartingWebApp/Internal/Generated/WolverineHandlers/GET_api_e1.cs b/src/Http/CrazyStartingWebApp/Internal/Generated/WolverineHandlers/GET_api_e1.cs
deleted file mode 100644
index 92cc6ba3c..000000000
--- a/src/Http/CrazyStartingWebApp/Internal/Generated/WolverineHandlers/GET_api_e1.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-#pragma warning disable
-using Microsoft.AspNetCore.Routing;
-using System;
-using System.Linq;
-using Wolverine.Http;
-
-namespace Internal.Generated.WolverineHandlers
-{
- // START: GET_api_e1
- [global::System.CodeDom.Compiler.GeneratedCode("JasperFx", "1.0.0")]
- public sealed class GET_api_e1 : Wolverine.Http.HttpHandler
- {
- private readonly Wolverine.Http.WolverineHttpOptions _wolverineHttpOptions;
-
- public GET_api_e1(Wolverine.Http.WolverineHttpOptions wolverineHttpOptions) : base(wolverineHttpOptions)
- {
- _wolverineHttpOptions = wolverineHttpOptions;
- }
-
-
-
- public override async System.Threading.Tasks.Task Handle(Microsoft.AspNetCore.Http.HttpContext httpContext)
- {
-
- // The actual HTTP request handler execution
- var stringValueArray_response = Endpoint1.Get();
-
- // Writing the response body to JSON because this was the first 'return variable' in the method signature
- await WriteJsonAsync(httpContext, stringValueArray_response);
- }
-
- }
-
- // END: GET_api_e1
-
-
-}
-
diff --git a/src/Http/CrazyStartingWebApp/Internal/Generated/WolverineHandlers/GET_api_e2.cs b/src/Http/CrazyStartingWebApp/Internal/Generated/WolverineHandlers/GET_api_e2.cs
deleted file mode 100644
index 5ce40bdf6..000000000
--- a/src/Http/CrazyStartingWebApp/Internal/Generated/WolverineHandlers/GET_api_e2.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-#pragma warning disable
-using Microsoft.AspNetCore.Routing;
-using System;
-using System.Linq;
-using Wolverine.Http;
-
-namespace Internal.Generated.WolverineHandlers
-{
- // START: GET_api_e2
- [global::System.CodeDom.Compiler.GeneratedCode("JasperFx", "1.0.0")]
- public sealed class GET_api_e2 : Wolverine.Http.HttpHandler
- {
- private readonly Wolverine.Http.WolverineHttpOptions _wolverineHttpOptions;
-
- public GET_api_e2(Wolverine.Http.WolverineHttpOptions wolverineHttpOptions) : base(wolverineHttpOptions)
- {
- _wolverineHttpOptions = wolverineHttpOptions;
- }
-
-
-
- public override async System.Threading.Tasks.Task Handle(Microsoft.AspNetCore.Http.HttpContext httpContext)
- {
-
- // The actual HTTP request handler execution
- var stringValueArray_response = Endpoint2.Get();
-
- // Writing the response body to JSON because this was the first 'return variable' in the method signature
- await WriteJsonAsync(httpContext, stringValueArray_response);
- }
-
- }
-
- // END: GET_api_e2
-
-
-}
-
diff --git a/src/Http/CrazyStartingWebApp/Program.cs b/src/Http/CrazyStartingWebApp/Program.cs
index 991ae7ba7..1c483ffe7 100644
--- a/src/Http/CrazyStartingWebApp/Program.cs
+++ b/src/Http/CrazyStartingWebApp/Program.cs
@@ -13,7 +13,7 @@
builder.Services.AddWolverine(c =>
{
//c.ApplicationAssembly = typeof(Endpoint1).Assembly;
- c.CodeGeneration.TypeLoadMode = TypeLoadMode.Static;
+ //c.CodeGeneration.TypeLoadMode = TypeLoadMode.Static;
});
builder.Services.AddWolverineHttp();
builder.Services.AddHostedService();
diff --git a/src/Http/Wolverine.Http/HttpChain.EndpointBuilder.cs b/src/Http/Wolverine.Http/HttpChain.EndpointBuilder.cs
index 5fae1e50b..13b88521d 100644
--- a/src/Http/Wolverine.Http/HttpChain.EndpointBuilder.cs
+++ b/src/Http/Wolverine.Http/HttpChain.EndpointBuilder.cs
@@ -72,7 +72,17 @@ public RouteEndpoint BuildEndpoint(RouteWarmup warmup)
var handler = new Lazy(() =>
{
this.InitializeSynchronously(_parent.Rules, _parent, _parent.Container.Services);
- return (HttpHandler)_parent.Container.QuickBuild(_handlerType);
+
+ try
+ {
+ return (HttpHandler)_parent.Container.QuickBuild(_handlerType);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidOperationException(
+ "Wolverine may be having trouble with concurrent access to the same route at startup. Set the WolverineHttpOptions.Warmup = Eager to work around this problem",
+ e);
+ }
});
requestDelegate = c => handler.Value.Handle(c);
diff --git a/src/Http/Wolverine.Http/HttpGraph.cs b/src/Http/Wolverine.Http/HttpGraph.cs
index 1fa8becc5..4179930ce 100644
--- a/src/Http/Wolverine.Http/HttpGraph.cs
+++ b/src/Http/Wolverine.Http/HttpGraph.cs
@@ -95,7 +95,7 @@ public void DiscoverEndpoints(WolverineHttpOptions wolverineHttpOptions)
foreach (var policy in wolverineHttpOptions.Policies) policy.Apply(_chains, Rules, Container);
- _endpoints.AddRange(_chains.Select(x => x.BuildEndpoint(RouteWarmup.Lazy)));
+ _endpoints.AddRange(_chains.Select(x => x.BuildEndpoint(wolverineHttpOptions.WarmUpRoutes)));
}
public override IChangeToken GetChangeToken()
diff --git a/src/Wolverine/Codegen/ServiceLocationPlan.cs b/src/Wolverine/Codegen/ServiceLocationPlan.cs
index 9151dff40..cd6e49a86 100644
--- a/src/Wolverine/Codegen/ServiceLocationPlan.cs
+++ b/src/Wolverine/Codegen/ServiceLocationPlan.cs
@@ -18,6 +18,17 @@ protected override bool requiresServiceProvider(IMethodVariables method)
public override string WhyRequireServiceProvider(IMethodVariables method)
{
+ if (Descriptor.IsKeyedService)
+ {
+ if (Descriptor.KeyedImplementationFactory != null)
+ {
+ return
+ $"The service registration for {Descriptor.ServiceType.FullNameInCode()} is an 'opaque' lambda factory with the {Descriptor.Lifetime} lifetime and requires service location";
+ }
+
+ return $"Concrete type {Descriptor.KeyedImplementationType.FullNameInCode()} is not public, so requires service location";
+ }
+
if (Descriptor.ImplementationFactory != null)
{
return
diff --git a/src/Wolverine/Wolverine.csproj b/src/Wolverine/Wolverine.csproj
index 1b7701654..f0b862e6f 100644
--- a/src/Wolverine/Wolverine.csproj
+++ b/src/Wolverine/Wolverine.csproj
@@ -4,7 +4,7 @@
WolverineFx
-
+