11 ms·
I’m a Dev doing mostly C# and JS. I’ve heard some of the complaints on HN mentioning DI and really don’t get it. I honestly feel like it makes my code cleaner
by shireboy 6y ago
I’m a Dev doing mostly C# and JS. I’ve heard some of the complaints on HN mentioning DI and really don’t get it. I honestly feel like it makes my code cleaner and more testable. For example, I don’t have to care where my IFooService comes from or how best to instantiate and dispose, I just request one in the constructor. For a framework to be flexible, you need _some_ plugin capability. Asp.net seems to do pretty good at giving you nice defaults but letting you swap out with DI. All my dependencies are laid out nicely in one place (Startup.cs) and then used throughout. DI gives you that and I’m glad that it’s baked in now as opposed to having to pick a 3rd party. Maybe I’m biased, though. Help me understand why NOT to use DI? Is it just moving people’s cheese or are there other reasons?
- mikewhy 6y agoNodeJS has had various libraries to mock dependencies for a long time. So for me, I've always seen it as an extra layer on top of something that was already possible.
- nurettin 6y agoDo use DI, it's great. It helps with structuring into entity/model/service/controller and treats DI providers as a global resource. But don't require configuration and instantiate lazily as a class member like a sane framework instead of having to pass it to constructors.
- jolux 6y agoConstructor injection is the preferred way to do DI because construction is a strong guarantee that an object’s state is properly initialized.
- mumblemumble 6y agoIn .NET, the usual convention is that you make required things constructor arguments, so that there's no room for confusion. Personally, I quite like that quite a bit compared to platforms and frameworks where the convention seems instead to be, "RTFM or die (at run time)."
- mwcampbell 6y ago> In .NET, the usual convention is that you make required things constructor arguments, so that there's no room for confusion. Except in Windows Forms, where the norm is a zero-argument constructor and setting everything via properties, because that approach works with component-based design-time tools. Come to think of it, I think WPF and its descendants do the same.
- ygra 6y agoYou can tell the designer how a particular type has to be created if it doesn't have a parameterless ctor, but yeah, it's generally easier to do it that way.
- mumblemumble 6y agoIt's been a while since I touched either WinForms or WPF, but, if I recall correctly how things worked, I don't think this is actually an exception to the convention. Don't they also make everything optional? In which case, the correct way to follow the pattern would be to also leave the constructor parameterless and configure everything via properties.
- KallDrexx 6y agoConstructor DI is extremely important though, because time and time again lazily injected dependencies via properties results in circular dependencies and sometimes missing dependencies that fail at runtime. I'm not talking about simple cycles either, every time I have seen lazy dependency injection done has ended up in an A -> B -> C -> D -> A scenario. Passing required dependencies by constructors makes this extremely apparent, not just to the DI framework but to the developers themselves. With constructor injection I can immediately grasp exactly what dependencies an object depends on without even going into the full code flow to look at all the code to find all the IOC container calls. Edit: Also constructor injection is critical for testing dependency injection. IT allows you to have automated tests that construct every relevant object using the same DI setup as your live application and you can verify that the DI framework can resolve dependencies for everything. If your DI is lazily done this cannot happen unless you explicitly call all code flows, opening yourself up to runtime errors that may be missed. Unit tests won't catch this because the dependencies of your production site will be different than the dependencies of your test scenarios.
- HeyHoJoe 6y agoGoing off of the dot net core 5 release thread, I assume it’s because of misunderstanding or lack of familiarity with the platform. There was a very confused top level comment that seemed to be complaining about DI and dependency drilling down several layers. That’s just not using DI at all. In general DI is a great pattern that encourages lose coupling and testability, so I also don’t get the complaint.
- mattmanser 6y agoIf you're talking about my comment, you couldn't be further from the truth. I've actually worked with C# for over 15 years now and written apps with (in order of age) VBScript, webforms, web services (the MS SOAP stuff), MVC 1, MVC 2, MVC 3, MVC 4, Web API, Web API 2, the OData one I forget the name of and asp.net core. Oh and Silverlight. I've probably missed something. On yeah, WCF. And even WWF! Basically EVERYTHING web-related to C#. Plus enough work in PHP, Python, Ruby, Express, etc. to be able to compare different approaches. And even sometimes VB.net, I've maintained and then migrated entire code-bases from that to C#. I'm not entirely sure what more familiarity I need? I'd also note that there are a lot of other people agreeing with my in that thread, almost all of whom show a decent technical understanding. And it's got a lot of upvotes. But, even if I "misunderstood" or have a "lack of familiarity", that speaks of how poor the design/documentation actually is. If you can so easily shoot yourself in the foot with it, it's not fit for purpose.
- HeyHoJoe 6y agoI don’t know if it was your comment, but you can tell me you’re the queen of Scotland for all I care. Just look at your complaint above in this thread about DI and how no one can make sense of it. If you have so much experience you hide it well.
- mattmanser 6y agoFunny, I've just checked those comments and again, a bunch of people agreeing with me. Are you wearing your "I can only see comments that back my biases" glasses? To me, it's clear that some people love DI. SOME. Use it if you want. I don't want to. Stop dictating what's "good" code to experienced developers. If it helps you, fine, but it hinders me.
- mattmanser 6y agoIf you don't want to write any unit tests, for which there are a myriad of reasons not to, whether you're prototyping, throwing together a small once and done for a client, etc. Then it's just a massive waste of time and gets in the way. I really feel that you (and Microsoft) have completely lost sight of the reason why DI was ever even necessary and have become blind to just how much extra code it generates. The only reason was to inject mocks, and people hand-wrung for ages over it because the code to do so infects all the other code. Then people started to try and back justify it with IoC, but it's never really been a convincing argument. It's also something that if you're not working regularly with it can be very mysterious and when it fails, fails at run-time, quite inscrutably sometimes. From my perspective it's just boilerplate magic that if you actually need it, fair enough, but if you don't is a persistent, nagging, pain in the ass.
- RobCrusoe 6y ago> If you don't want to write any unit tests, for which there are a myriad of reasons not to, whether you're prototyping, throwing together a small once and done for a client, etc. Then it's just a massive waste of time and gets in the way. A massive waste of time? Adding a constructor and one line to startup.cs is a massive waste of time? Just how long does it take you? > It's also something that if you're not working regularly with it can be very mysterious and when it fails, fails at run-time, quite inscrutably sometimes. If DI fails it’s usually just because you’ve forgotten to add that one line to the startup.cs, and the error you get will tell you that. Can you give me a concrete example of how DI is inscrutable?
- chunkyfunky 6y ago"The only reason was to inject mocks". Must disagree...the reason for DI is to support the Dependency Inversion Principle : "High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g. interfaces)." Won't even go into the host of side-benefits that are gained from adhering to the DIP. In C# the idiomatic way to achieve this is via constructor injection, which is made much easier to manage in ASP.Net with a DI library that works with the framework for you (either the built in one or AutoFac / SimpleInjector, etc.). But you don't have to use a library; many times I'm writing a simple-ish console app and just use good old "Poor Man's DI" where I manually construct my object graphs at startup.
- dustinmoris 6y agoTo be fair there are some very questionable design decisions with ASP.NET Core. The whole way of initialising a Host and configuring things around it is a huge myriad of nested factories and builders which honestly looks like a huge mess. It's hugely overcomplicated for 95% of web applications in my opinion.