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 - +