You still need to make sure that everything works, but that's what tests are for, and this has to be checked regardless of your tech stack.
Of course, they had a massive backwards compat break when moving from the regular aspnet to aspnet core, here's hoping nothing like that happens in the next 10-15 years..
With enough experience you can accomplish pretty much everything using just the minimal API and router. HttpContext is the heart of AspNetCore. If you can get your hands on instances of it within the appropriate application context, you can do anything you need to. Everything else is dependent upon this. The chances that HttpContext can be screwed with are very, very low. There are billions of dollars riding on the fact that this type & API remains stable for the next decade+.
The DI pattern is simple & clean at this scale. In my top-level program I define my routes like:
app.Map("/", Home.HandleRequest);
app.Map("/login", Login.HandleRequest);
app.Map("/account/new", NewAccount.HandleRequest);
app.Map("/{owner}", OwnerHome.HandleRequest);
And then I have HandleRequest implementations like: static async Task HandleRequest(HttpContext context, SQLiteConnection sql)
static async Task HandleRequest(HttpContext context, SQLiteConnection sql, string owner)
etc...
The actual HandleRequest() method can do anything, including concerns like directly accepting and handling web socket connections.Java on the other hand had an implementation of generics that made Container<X> just a Container so you could mix your old containers with generic containers.
Now Java's approach used type erasure and had some limitations, but the C# incompatibility made me suffer every day, that's the cultural difference between Java and a lot of other languages.
It's funny because when I am coding Java and thinking just about Java I really enjoy the type system and rarely feel myself limited by type erasure and when I do I can unerase types easily by
- statically subclassing GenericType<X> to GenericType<ConcreteClass>
- dynamically by adding a type argument to the constructor
- mangling names (say you're writing out stubs to generate code to call a library, you can't use polymorphism to differentiate between
Expression<Result> someMethod(Expression<Integer> x)
and Expression<Result> someMethod(Expression<Double> x)
since after erasure the signature is the same so you just gotta grit your teeth and mangle the method names)but whenever I spend some time coding hard in a language that doesn't erase generic parameters I come back and I am not in my comfortable Java groove and it hurts.
If you're up for it you should give it another try. Your example of subclassing GenericType<X> and GenericType<ConcreteClass> may be supported with covariance and contravariance in generics [1]. It's probably not very well known among C# developers (vs. basic generics) but it can make some use cases a lot easier.
[1] https://learn.microsoft.com/en-us/dotnet/standard/generics/c...
People talk about tradeoffs with GC, the worst one is that I've seen an occasional game that has a terrible GC pause, for instance Dome Keeper based on Godot which also runs in .NET. I used play a lot of PhyreEngine (also .NET) games on the Playstation Vita and never noticed GC pauses but I think those games did a gc on every frame instead of letting the garbage pile up.
Not all GCs are created equally either. Unity, for example, is based on an ancient version of Mono and so it uses the Boehm GC which is significantly slower than the one used by .NET. Godot probably has two GCs because it primarily runs GDScript (their custom language) and only supports using .NET in a separate engine build. They'll all have their own performance characteristics that the developer will need to adjust for.
Correct me if I'm wrong but allowing this would mean the called api might insert objects wholly unrelated to X. This would break every assumption you make about the container's contents. Why would this ever be allowed or wanted?
Microsoft created the ".NET Standard" for this. Literally anything that targets .NET Standard 1.0 should work from circa 2001 through modern day 2025. You still get the (perf) benefits up the runtime upgrade which is what the blog post is about.
What are you looking for out of .NET? The staple packages don't go away as often as in languages like NodeJS
Scott Hanselman has a very short blog on how 20 year old code is upgraded to the latest .NET in just a few short minutes: https://www.hanselman.com/blog/upgrading-a-20-year-old-unive...
This seems unlikely. Do you have a source?