Live data from Hacker News

.NET 5.0

devblogs.microsoft.com

431–440 of 466 posts

Re: .NET 5.0

#431
post #418

Earlier quoted context omitted.

Making software harder to read, write, and maintain in the name of making unit tests easier to read, write, and maintain is putting the cart in front of the horse.

The age old TDD dilemma, that treats the test suite as first class, rather than the end user's experience.

The end user being the programmer?

I find it humorous that so many programmers still can't see past the end of their nose when it comes to designing code for application testing.

An application is deliverable. That means testable and deployable with a consistent, repeatable process. Anything short of that is not an application, it's a prototype.

Yes, it takes longer to deliver up front, but it removes the long tail of maintenance. Getting a low quality product out of the door makes for a bad user experience and garners you a bad reputation.

The test suite _should_ be a first class citizen.

Re: .NET 5.0

#432
post #328

Earlier quoted context omitted.

I can't think of anything other than Java that's as tedious to write as C#/ASP.Net. With Java and C# code you spend a siginifcant amount of your time messing with the complexities of the language itself instead of dealing with your business problem. The mixture of generics and static typing is particularly pernicious. I really hope Go 2.0 doesn't end-up going down the generics rabbit hole.

Can you give some concrete examples of how C# is tedious compared to go? Things like var filtered = purchases.Where(x => x.Name.Contains("Sean")); and var grouped = purchases.GroupBy(x => x.Buyer).Where(x => x.ToList().Count > 10).ToDictionary(x => x.Buyer, x => x.ToList()); etc. come up a lot in day to day programming and always feel tedious to me in go. The first example in go looks something like filtered := []pur…

Same experience here for Java. I always have a hard time understanding the arguments against it. The platform and tooling far exceed that of Go and I've never found the writing of actual code to be anywhere near the bottle neck in the entire development process. And while I've never worked professionally with C#/.NET, I imagine it's a very similar experience.

Re: .NET 5.0

#433

Earlier quoted context omitted.

I think the OP is referring to accessing the config 5 layers down from the controller. I've run into it myself. To be able to do that, you have to add Options to the constructor of every class in the chain and then configure DI for it. It just has bad code smell. On my last project, I just assigned the configs to a static class that's available everywhere and the code was just simply much cleaner.

Why does something 5 layers down need all the config values?

Not necessarily all options, but just maybe settings for connection to some 3rd party server. You will need the configs.

Re: .NET 5.0

#434

Earlier quoted context omitted.

Oh yes you'd definitely get booted for using F# in a C# shop. I love F# but would never use it at my current job because nobody else on my team knows anything about FP, even though the language itself can be learned in about a week since it's so simple.

My comment was a glib comment and wasn't supposed to be taken too seriously.

Fair enough, but it also outlines a bit of truth that you shouldn't necessarily go against the grain of the programming culture of a workplace just due to personal preference.

Re: .NET 5.0

#435

Earlier quoted context omitted.

The type system in typescript is a lot more advanced than the one available in C#.

This is due to the fact that typescript needs to interop with javascript, and existing js ecosystem has some very weird "typing" decisions. In TypeScript you can express types that you would never ever do in a "sane" language like C# which has proper typing design in place.

I have wanted union types plenty of times in C#.

Nullability analysis was recently added to C# (nullable reference types) but it was in tyepscript first.

Re: .NET 5.0

#436
post #329
post #288

Earlier quoted context omitted.

Goroutine like .NET IAwaitable/Task both abstract the thread away. No one thinks about threads when programming async/await code despite in any await keyword a thread change can happen. Both solve the same problem with the same technique (under the hood it is all the same). One language had the benefit of late birth (go), the other suffers with its friends through a library/language migration (C#, C++, Java, JavaScri…

Worth noting that "late birth" is not the only thing at play here - Rust _had_ green threads at one point and removed them - only to add async/await later.

async/await has underpinnings in monadic computation expressions (via F#/Haskell). There are some benefits to the model, despite a lot of its detractors in the thread here. Such as it is possible to work with multiple monads (many languages that support async/await are not strict about which monad they rewrite for; C# supports any Monad that has a GetAwaiter() method of the right shape, JS supports any object with a then() and/or catch() of the right shape, etc).

While async/await is nowhere structurally as capable/composable as for instance Haskell's do notation, it's still more composable than a lot of alternatives and a lot of manual thread management techniques.

The biggest thing though is that these concerns are orthogonal. You can have green threads backing an async/await monad (with some caveats), but you can't as easily swap in anything that follows monad rules into code written specifically just for green threads. (Python makes you explicitly define your threading model before using async/await; the others provide methods to configure it.)

Which is to say "late birth" isn't really a consideration in async/await, it's as much a consideration of flexibility/composition of abstractions. JS, for example, needed that flexibility/composition in the wild west of multiple disparate Promise implementations early on, and may need it again if/when Browsers ever decide to support proper multi-threading whether it is green threads or something else. In such a future you should still be able to compose existing async/await code without modifying it, even as you take advantage of newer threading options.

Re: .NET 5.0

#438

Earlier quoted context omitted.

I don't know how long ago you're speaking about, but Silverlight and Flash were at their end of days even back in ~2006. Apple just nailed the coffin shut. That's not Microsoft's fault, there was a sea change in the industry away from browser plugins and these types of platforms. Apropos WCF, well we got JSON and no-one outside of "enterprises" were doing SOAP/WSDL et al any more and it was pretty much done. That's n…

Silverlight wasn't even born until 2007, so it's hard to see how it was dead in 2006. :) Or maybe you're saying it was DOA?

> Or maybe you're saying it was DOA?

Pretty much. The only time I've ever seen Silverlight apps in the wild were for streaming use (Sky/Now TV for example).

Re: .NET 5.0

#439
post #103

Earlier quoted context omitted.

I'm mainly interested in one statement: > it's just pointless boilerplate trash, which C# has been getting rid of excellently Could you elaborate on how you feel C# avoided this? From my point of view the only alternative (to DI with constructor injection) is static members somewhere, which does not scale. Maybe property injection, but ugh.

I think they want to use something more like an environment contextual config fetcher instead. For example: test.appsettings.json {"db-url":"test.url.here"} prod.appsettings.json {"db-url":"prod.url.here"} Now in the code: Settings.fetch("db-url"); // Will return the test one if environment variable says we are running under test environment, else will return the prod one.

The DI-based configuration system can be configured to do exactly that. Though yes, the configuration is maybe harder than it should be simply because it isn't on by default.

A lot of the complexity in the configuration system exists to enable a lot of configuration options. I have some ASP.NET applications that get some configuration from Environment Variables on the host machine, some from environment-specific config files, some from a configuration service (specifically Azure Key Vault), all without any of my DI-injected downstream components specifically needing to know which source provided specifically which configuration key. For the DI injected things it is just `config["db-url"]` or maybe type-safe class if I DI-inject an IOptions (or add my type-safe classes directly to the DI without the IOptions wrapper, which is another configurable option).

It's absolutely a very complex system, but with great complexity comes great flexibility (to badly paraphrase the Spider-Man mantra).

Re: .NET 5.0

#440

Earlier quoted context omitted.

If you go too far with DI, the saying is "everything happens somewhere else." Some feel it can be needlessly complex to troubleshoot such a system or gain understanding of it if you weren't one of the original authors.

Don't need DI to make your program so abstract no one can follow it. Wouldn't even say DI makes it easier to do because you can accomplish the same thing by just newing up objects.

That's related to my rule of when DI is being abused: if you can't just new up the objects by hand (perhaps in a unit test somewhere), then you should rethink your use of DI.

I've seen projects where the dependency object graph exceeded anything you could possibly new up yourself, due to circular dependencies and impossibly complex scope rules. That's definitely a sign of a program so abstract no one can follow it.

(Microsoft's very simple DI container that's now standard out-of-the-box in .NET Core has somewhat strict limits on DI scopes and disallows circular dependencies, so it's one of the better ones.)

Post reply on HN