I'm having an issue with the MapControllers method of UseEndpoints.
my thought process:
For the class
Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModel
when injected into the apply method of an IControllerResourceMapping, the controllers that are located on the Controllers property are based on the assembly the dervied Startup file is in (which calls IApplicationBuilder.UseRouting/IApplicationBuilder.UseEndpoints).
I have a TestStartup (assembly B) that extends Startup (assembly A) which calls the IApplicationBuilder.UseRouting/IApplicationBuilder.UseEndpoints behaviour, where UseEndpoints has MapControllers in it.
I only get controllers in assembly B, not the ones in assembly A (the ones i want). Is this expected behaviour?
This behaviour is inside of a framework, will try to get a minimum code sample asap.
A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
A compatible installed .NET Core SDK for global.json version [5.0.100-alpha1-014696] from [C:\Users\x\Documents\git\github\AspNetCore\global.json] was not found
Install the [5.0.100-alpha1-014696] .NET Core SDK or update [C:\Users\xDocuments\git\github\AspNetCore\global.json] with an installed .NET Core SDK:
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.400 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.403 [C:\Program Files\dotnet\sdk]
2.1.500 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.1.509 [C:\Program Files\dotnet\sdk]
2.1.600-preview-009472 [C:\Program Files\dotnet\sdk]
2.1.600-preview-009497 [C:\Program Files\dotnet\sdk]
2.1.800-preview-009696 [C:\Program Files\dotnet\sdk]
2.2.101 [C:\Program Files\dotnet\sdk]
2.2.102 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]
Host (useful for support):
Version: 3.0.0
Commit: 7d57652f33
.NET Core SDKs installed:
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.400 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.403 [C:\Program Files\dotnet\sdk]
2.1.500 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.1.509 [C:\Program Files\dotnet\sdk]
2.1.600-preview-009472 [C:\Program Files\dotnet\sdk]
2.1.600-preview-009497 [C:\Program Files\dotnet\sdk]
2.1.800-preview-009696 [C:\Program Files\dotnet\sdk]
2.2.101 [C:\Program Files\dotnet\sdk]
2.2.102 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
@wisepotato thanks for contacting us.
This is likely due to changes in hosting and the fact that you are using a derived startup class. Check the following:
IHostEnvironment.Name to make sure it has the right value.If you have a standard Program.cs from .net core 3.0 having multiple startups is not going to work well.
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
In 3.0 the ConfigureServices callback gets queued inmediately when you call UseStartup and the result if you call UseStartup again is that it will queue another ConfigureServices callback from that second Startup class, which will result in both Startup callbacks running, which might not be what you want.
Any way to have derived startup classes for e2e tests?
I wouldn't want both startup classes to queue ConfigureServices..
@wisepotato I'm not sure there's any way with the way the new hosting works, other than passing a flag or similar to the CreateWebHostBuilder method and check that flag to avoid calling UseStartup in the first place.
@davidfowl @Tratcher Thoughts?
To rephrase my question: is my current setup with derived startups the way to go? Is this not common practice? I need different configs for different testing enviornments (disabling middleware, spoofing user authentication, different naming convention for routes etc..)
Usecase: testing client generated ids in JsonApiDotNetCore (a framework that implements json:api spec). In the codebase we have an example project dedicated to e2e testing. Its default Startup class has the client-generated ids option disabled, and we have a separate startup class ClientGeneratedIdsEnabledStartup that derives from Startup which enables this feature. It is used only for that particular test case.
We can avoid the problem for now by moving ClientGeneratedIdsEnabledStartup to the same assembly as Startup, but this file shouldn't (have to) be in this assembly.
@maurei see Environments https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-3.0
This seems like a mixture of concerns, let's say I have feature switches 1 till 35. Your solution would require me to facilitatie this with:
c#
if(env.IsEnvironment("testing_One"){
FeatureSwitchOne();
}
if(env.IsEnvironment("testing_Two"){
FeatureSwitchOne();
}
.
.
.
if(env.IsEnvironment("testing_35"){
FeatureSwitchThirtyFive();
}
I think environment switching is enough for most people, but If i want to test 1 to 35 with combinations of them, I could in theory have 35*34 = 1190 combinations i would need to clutter my startup.cs with.
So it will not do it for me :(
Or in your dev and test environments you load the individual switches from the dev/test config.
How would I approach that? Maybe this is me misunderstanding but I would like individual tests to be able to set switches, from the test itself.
Is this not common practice? If not, then I guess i'm misunderstanding.
Tried to use WebApplicationFactory in a test with an external startup class as in https://github.com/aspnet/AspNetCore.Docs/issues/7063#issuecomment-414661566, but the error persists.
How would I approach that? Maybe this is me misunderstanding but I would like individual tests to be able to set switches, from the test itself.
Is this not common practice? If not, then I guess i'm misunderstanding.
The theory was to inject IConfiguration into Startup and then have it query configuration keys to enable/disable features. Tests can provide in-memory configuration overrides to toggle individual features.
So my startup knows about how tests are run? I mean I want to disable the middleware in my tests but I don't want that to EVER happen in production.
Is this really the idea? Because that would mean all the options i want to test/disable in my tests should be checked in my startup, creating a lot of checking and passes. While I could also override it in a clean new startup.
So my question is: why not both ways? I see uses for your version, but my version seems.. cleaner. Maybe I'm mistaken.
Startup controls how your app runs in any environment. If you want to provide a different startup for tests, that's up to you.
Startup controls how your app runs in any environment. If you want to provide a different startup for tests, that's up to you.
So thats kind of my point, my test startup has to be in the assembly i'm testing. Not in my testing assembly, where I would expect them to be.
But yeah, that's atleast a start and one way to do it.
Thank you for contacting us. Due to no activity on this issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.