Live data from Hacker News

.NET 5.0

devblogs.microsoft.com

381–390 of 466 posts

Re: .NET 5.0

#381

So, on the plus side with the new .net, I recently made a .net core web app on Linux, and generally it's been pretty easy. I'm also impressed at just how fast asp.net core is compared to asp.net, the time it takes to open your site in debug mode has dropped dramatically, from what used to be 1/2 minute in asp.net to a few seconds in .net core. On the bad side? Mainly the asp.net core team and their push for Dependenc…

The forced DI pattern makes sense here because:

Most DI containers are not just injectors, but they also manage life cycles/scopes of objects: singleton/transient/scoped.

Since in web development, a request hitting a controller endpoint is typically short lived and most objects and services are tied to the main request scope, it makes sense that all your objects should live and die when the request is made and completed. What is the cleanest way to manage this life cycle scopes? Dependency Injection. Most of your object/services will be "scoped", with fewer being transient (aka a pool of reusable objects) and the fewest being singletons that will survive individual requests.

A second side effect of DI, it forces you to code by convention. Conventions make maintaining the code 6 months from now a breeze. Want to add a new service? Just let it inherit from an IService and consume it in 10 places, it will auto find/inject your new code. No need to new() up and dispose your service in 10 place.

Do all of this without DI and use only constructors + Dispose(). Good luck! Mercy on the poor soul who has to maintain all that mess.

If you want to go a step further, instead of having 100's of IService and each constructor declaring they each need 10 of them (ILoggerService, IAccountService, IEmailService, IStockService etc etc)... that also becomes very gross in large projects: so to go a step further, use the Mediator pattern. You can either implement your own (super easy) or use the Mediatr nuget package. Then each service becomes much cleaner. Each service then only has 1 method that does work. It also ties in nicely with the Unit of Work pattern.

Why should my IStockService inject the IEmailService when I just want to check stock levels with GetLatestStock() that return an int and does no other work?

Lets say the IStockService has 15 methods to do with stock and 10 dependencies. So on each request where you depend on IStockService, you would also pull in the 10 dependencies and their inner dependencies which may add 1 second to your response time and uses 10mb RAM. But all you wanted to was check stock which takes 10ms and 1mb RAM.

This is exactly the scenario that mediator pattern can help solve. So your 15 methods become 15 individual classes, each pulling in ONLY the dependencies it needs and nothing more. Your file and git commits stay small too which makes everything more digestible (less than 100 lines of code if lucky),

So my favourite setup is DI + Mediatr. Each file/class has only ONE purpose to exist and only one reason to be pulled into a dependency tree, all while DI will manage their life cycles.

Edit: For those downvoting, please go read "Dependency Injection by Mark Seemann" and also read https://docs.microsoft.com/en-us/aspnet/core/performance/per... . Then try to build your own framework from scratch. Do it. Then come crawl back and upvote this comment. I've have a ton of experience with this stuff and have built 2 or 3 custom frameworks. The core trait that keeps everything sane and fast is to keep things simple, keep dependencies low, keep hot paths lean. The easiest way to get to that place is DI + Mediatr and to break some services into their own api's if they get deployed too often. It's that simple.

Re: .NET 5.0

#382

So, on the plus side with the new .net, I recently made a .net core web app on Linux, and generally it's been pretty easy. I'm also impressed at just how fast asp.net core is compared to asp.net, the time it takes to open your site in debug mode has dropped dramatically, from what used to be 1/2 minute in asp.net to a few seconds in .net core. On the bad side? Mainly the asp.net core team and their push for Dependenc…

You also have to understand that shoving async down our throats is part of the philosophy of how aspnet core and kestrel (built ontop of libuv) is implemented: the whole stack is built to run async and with DI in mind. aspnet core itself uses the same DI system to manage itself.

No part of aspnet core is built to run synchronous. Its all async all the way down.

Re: .NET 5.0

#384

Earlier quoted context omitted.

> Azure will win you over from AWS every time. Going to have to disagree here. That might be the case if Azure was not literally a tire-fire. I have been using Azure for work and it's the most frustrating, inconsistent, often-broken, confusing and stress-inducing cloud service that my teammates and I have ever been subjected to. It left such a bad taste that I am quite certain I would flat-out refuse to use it again…

Gee.. Sounds like you have had an awful time of it. Any chance you could speak more of some of the issues you encountered? We are looking at cloud providers and was kinda leaning towards Azure.

My advice, stay the f*ck away from Azure as far as you can. It’s the biggest clusterfuck I have ever had to deal with. Unless you are a Microsoft Gold Partner and you simply buy every shit which your Microsoft Account Manager tells you then you have no reason to use Azure. Unlike the Google Cloud or AWS, Azure has not a single service which is unique or good in any particular way. On the other side, they have many services which are uniquely so bad that they are unusable in Azure.

Example of unique services in the GCloud: Spanner, Firestore, BigQuery,...

AWS: Face recognition service and other neat things

Uniquely fucked up in Azure: Functions, Web Apps, Storage, Application Insights (FML!), ... many many more

Re: .NET 5.0

#385

Earlier quoted context omitted.

>and you're in for an even bigger nightmare if you want to separate business logic and web code into two projects (which is a pretty common design). I've given up with the config DI and just assign them all to static variables. So you have static variable in web project and then add reference to web project to obtain that config? Do I get that right? I never felt like config DI was a problem once you did all the stuf…

To me it's just so pointless, here's an example: using Microsoft.Extensions.Configuration; //extra line using Microsoft.Extensions.Options; //extra line public class AdminController : Controller { IOptions settings; //extra line public AdminController(IOptions settings) //extra code { this.settings = settings; //extra line } public void RandomMethod() { var a = settings.Value.FinallyMySetting; // 5 extra lines to acc…

> it's just pointless boilerplate trash,

I don't regard the "ConfigurationBuilder" and following lines as "boilerplate" exactly, since by not using the default HostBuilder and instead including that code, you are making choices.

Specifically, you are choosing to pull in settings from "appsettings.json", "appsettings.{env}.json" and then environment vars, in that order, and specifying that both files are optional and should reload on change.

You can make other choices, with other code.The code is there to "configure the config", i.e. to make those choices.

Re: .NET 5.0

#386
post #326

Earlier quoted context omitted.

> If you're writing modern nodeJS you're probably not using callbacks or promises (directly) anymore I get that some people prefer async/await (I actually find explicit Promises clear enough that I don't have any strong preference, myself), but why wouldn't you be using explicit callbacks, which in my JS experience (mostly frontend, but also fairly modern) are super common outside of promises, which is the only place…

Yeah, callbacks are fine until you get a big stack of them (so-called “callback hell”). Promises were the touted solution to callback hell, async/await the touted solution to endless promises chaining. While async/await is (tasty) syntactic sugar for promises, I think it’s a real improvement over callbacks - it’s one less argument to every function (because of promises) and I think it’s easier to read: there tends to…

The weird thing about async/await is that it gets you out of deeply nested callbacks into, pretty much by definition, exactly equally deeply nested async function calls. The only thing that seems different is that it seems to be more common (but not any more or less supported, since you can obviously have named non-async functions and you can also have anonymous async functions) to call named functions in async/await and anonymous functions defined inline as callbacks with promises.

Re: .NET 5.0

#387
post #18

As someone who uses .NET daily, but loves Clojure and other functional programming paradigms - Records seem like a very compelling feature. Immutable data structures without any hassle to set up. Simply write “record” where you would normally write “class” and boom, you are working with immutable objects. This is one step closer to one the best features of Clojure IMO -everything is immutable. Additionally, there see…

Aren’t records pretty trivial to create as a custom class in C#?

Thing is, you can do it but with ceremony.

You have to override Equals() and GetHashCode() for starters. Then you also need to make sure you only have getters and no setters (or private setters). In some cases you need to make your empty constructor private and force a specific constructor to be used. If you have multiple constructors it means you will have different invariants which puts you in class land, you are better off with classes then anyway. Also if your immutable objects have many methods..that also puts you in class land.

Just that alone makes it cumbersome.

So a new record type that behaves somewhat like a struct would be perfect. Or the F# way, which is basically perfection.

Re: .NET 5.0

#388

It is a bit sad that so-called "native AOT" was not included in the release. When I heard last year that .NET 5 would support single-file binary, I expected it to be the same as something like Rust or Go would offer. But no, Microsoft changed the meaning of AOT and moved the goal post, introducing the real AOT as "native AOT". Thankfully they are aware of the issue, so I hope to finally see in when .NET 6, which will…

I find CoreRT covers a lot of my current AOT needs.

For me, one of the blockers was Winfows.Forms not working with AOT, which appears to have been resolved very recently:

https://github.com/dotnet/winforms/pull/4177

Post reply on HN