"Stop Using Singletons in .NET!" | Code Cop #009

"Stop Using Singletons in .NET!" | Code Cop #009

Nick Chapsas

5 месяцев назад

75,427 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

@NaveedKakal
@NaveedKakal - 20.01.2024 01:06

Nice haircut

Ответить
@digitalpacman
@digitalpacman - 19.01.2024 13:29

What exactly is hacky about registering with your IoC that ISingletonInstance = SingletonClass.Instance. Now it's testable. What's the hacky thing here?

Ответить
@ITR
@ITR - 18.01.2024 18:16

I mean, clearly their problem isn't the use of singletons, but the use of OOP

Ответить
@michaelkhalsa
@michaelkhalsa - 18.01.2024 08:21

In the right usage, singletons are beautiful and simplify code while improving performance.

If the only issue is creating mocks for testing, then this is not hard to do, provided a consistent approach is used.

Ответить
@Rafloka
@Rafloka - 18.01.2024 04:41

I really appreciate your non-dogmatic approach to these topics!

Ответить
@Naton
@Naton - 17.01.2024 15:54

I use it to store struct constants

Ответить
@user-xd3mt2qy1n
@user-xd3mt2qy1n - 17.01.2024 11:08

I would rather phrase it as "Avoid using Singleton... in Unity projects xD", and it's less about Singleton itself being at fault, but rather it often leading to clunky solutions by lazy programmers.

Time and time again I find some vague GameManager being referenced in various projects. First of, what does it do? Manage the game? I have no idea what that means. I look in the code and am shocked to find it doing so many things from starting a scene to scoring the player, updating UI, meaning there's a GameObject that needs to be carried around every scene and every other GameObject that depends on it must also be dragged in, making testing individual components a pain. And all this could have been avoided by separating concerns.

TL;DR: Avoid using Singletons if it's just your shortcut for every Game Object to be able to reference each other.</rant>

Ответить
@Herio7
@Herio7 - 16.01.2024 12:56

In my book there is nothing, literally nothing banned by default. The more obscure, against the steam just needs more explaination

Ответить
@Looooooka
@Looooooka - 15.01.2024 14:50

I was about to unfollow Nick when I read this title :D

Ответить
@MysticAngel3224
@MysticAngel3224 - 15.01.2024 11:48

Yeah, I don't like tech articles which are written in this fashion. The singleton pattern is one of many software designs which has its benefits and downsides (like many others). It is up to the developer to determine when it is appropriate to use a particular design pattern.

Ответить
@arpanmukherjee4625
@arpanmukherjee4625 - 15.01.2024 00:44

Your example is only making the case for "Don't use singletons" stronger. Your video is just trying to justify use of global variables. GameManager.Instance is a global variable. Being politically correct is not more important than practicing good engineering. I respect your work on .NET content creation a lot, but this video goes against all the good things I have learnt the hard way along my way.

Ответить
@arpanmukherjee4625
@arpanmukherjee4625 - 15.01.2024 00:36

To be honest, I have never come across a good use case for Singleton classes. Everytime I designed a solution with singleton, I immediately found a cleaner way to implement it with static classes or I was simply wrong in making it a singleton (and found a better lifecycle). Everytime the cleaner way was found by checking if I am leaking state or encapsulating it right. I often question, does my abstractions here make sense with the environment? Especially in concurrent programs, singletons or even heavy use of static state is dangerous, because they ARE global state. The person who said it, must be writing real applications for years and not toy ones for videos or courses. Enum values are the only singleton worthy objects 😂.

Ответить
@SeanAlunni
@SeanAlunni - 14.01.2024 15:24

Can't you just make "_games" static in an utility class?

Ответить
@FarukTahiraj
@FarukTahiraj - 14.01.2024 13:34

When I saw this on LinkedIn I KNEW you would make a video 😂😂

Ответить
@vargonian
@vargonian - 14.01.2024 02:26

I definitely want to hear more about your thoughts on us going too far with dependency injection in .NET.

Ответить
@Beacher1085
@Beacher1085 - 13.01.2024 16:02

Static Class vs Singleton - top of my mind:

Static is a keyword and Singleton is a design pattern

Static classes can contain only static members.

Singleton is an object creational pattern with one instance of the class.

Singleton can implement interfaces, inherit from other classes and it aligns with the OOPS concepts.

Singleton object can be passed as a reference

Singleton supports object disposal

Singleton object is stored on heap

Singleton objects can be cloned

Ответить
@qj0n
@qj0n - 13.01.2024 15:14

While I can agree that Singleton can have its place, the example of GameManager looks a bit off - I'd rather make it a DI Singleton. It'd rather have it as a DI Singleton as this is something you might create many instances of e.g. in tests, even if you can't see benefit of that at the beginning. And once you build an app around this class being singleton, you will have hard time refactoring it.

I use singletons mostly in areas related to hardware, where having multiple classes communicate with particular device would always be wrong

Ответить
@skgenius5410
@skgenius5410 - 13.01.2024 13:46

singletons are global variables by definition

Ответить
@nickbarton3191
@nickbarton3191 - 13.01.2024 12:35

The biggest problem is that without the ability to reset state, groups of unit tests of components that use it are likely to fail if run out of order. Unit tests must stand each in it's own right.
BTW the same goes for tests that use factory created objects that only produce one instance, they too are singletons.

Ответить
@Dimich1993
@Dimich1993 - 13.01.2024 06:16

So what did you mean we're going too far with DI in .NET?

Ответить
@dovh49
@dovh49 - 13.01.2024 00:20

Yes, let's hear what you have to say about DI!

Ответить
@derriennovak666
@derriennovak666 - 12.01.2024 21:30

I honestly dont even know how long it's been since I've implemented the singleton pattern myself. I mean, I did use DI to create singleton instances for me but that's it.

Ответить
@jessegador
@jessegador - 12.01.2024 20:39

That dude did not realized that the TaskManager in windows is an implementation of a singleton!

Ответить
@TalicZealot
@TalicZealot - 12.01.2024 18:36

Even old school AOC containers used Singletons for lifetime management. Ninject had SingletonScope and RequestScope, which Microsoft now gives us by default.

Ответить
@johanngerell
@johanngerell - 12.01.2024 17:30

"Never generalize"

Ответить
@digibrett
@digibrett - 12.01.2024 15:52

Please do expand on how MS is going too far with DI.

Ответить
@Thial92
@Thial92 - 12.01.2024 15:42

People who have barely any experience seem to be more opinionated than seniors nowadays. As long as you need dependency injection, mediator, interfaces, mocking then singletons will be your best friend. Static classes are also great for all sorts of extensions, helper methods, wrappers or even keeping some string values to prevent typos. Singletons exist specifically because they solve certain problems so claiming that they are bad design is just pure ignorance.

Ответить
@lucaslevandoski2946
@lucaslevandoski2946 - 12.01.2024 14:46

I swear to got that I can only hear "gay manager" not once "game manager"

Ответить
@PajakTheBlind
@PajakTheBlind - 12.01.2024 14:15

I'm down for criticism and overuse of DI

Ответить
@PajakTheBlind
@PajakTheBlind - 12.01.2024 14:11

While I like the series, the main takeaway from all of these is what differentiates a 'junior' from 'mid/senior' - there is always a nuance to using patterns/types/hammers/screwdrivers. All of these exist for a reason and you should never discard something because some talking head said it's an anti-pattern or some other thing.
My favourite thing is shallow understanding of stuff like SOLID/DRY/KISS and so on. Static analysis tools sometimes push you in these stupid directions.
If you have some 'accounting' software and some code in it responsible for calculating prices on invoice. The moment business requirement changes (due to changing law) it would be preferable to copy the whole code and alter it to adhere to new requirements and just pick the proper one based on date of generating the invoice or something. I've met people who would oppose such solution in past because it would somehow 'violate' some of these (sometimes arbitrary) rules, which in reality are just guidelines or heuristics.

Ответить
@devblizzard
@devblizzard - 12.01.2024 13:52

Awesome video. Thanks Nick! 🔥🔥🔥

Ответить
@finald1316
@finald1316 - 12.01.2024 13:32

Func bros be like "your code becomes impure once singleton state is arbitrarely changed by multiple sections of the code; it is like unsafe sex. Do you practice unsafe sex? ... ... ... oh... oh no."

Ответить
@ralphmaasgmailcom
@ralphmaasgmailcom - 12.01.2024 13:09

A singleton is useful piece in software development as you mentioned in your talk an use of caching in an application is not possible without the use of a singleton.

Ответить
@andreyandreev4636
@andreyandreev4636 - 12.01.2024 12:28

Any idea can be taken to the point of absurdity. The same story with singleton. Use it when you need it and do not hesitate to add some flexibility to it. Instance could be just place where to store the object (you have to do it anyway, doesnt matter how do you call it. Instance, or somefields in DI etc etc). Constructor might be internal to be available to unit tests to create lightweight test objects. DI might be performed by properties which accepts other objects by interfaces which could be mocked. And you'll have simple plain code for initialization

Ответить
@sachethana
@sachethana - 12.01.2024 10:54

Recently, GPT4 suggested me this pattern, and I was surprised. This video was a great learning opportunity to me as I was using Class(dot)Instance.MethodName earlier and now I am moving it to DI and its more testable too. Cheers!!

Ответить
@xnetc9
@xnetc9 - 12.01.2024 10:13

Singleton = bad... Jr developers introducing their big brains into development... causes a lot of issues in general development.

Ответить
@miroslavmakhruk4102
@miroslavmakhruk4102 - 12.01.2024 10:09

Well, I use singletones where I need them (both real and via DI) and I will keep doing that, Really bad advice IMO. ¯\_(ツ)_/¯

Ответить
@bosegeorge1425
@bosegeorge1425 - 12.01.2024 09:50

Please start having a subscription plan too. Buying each course is lot i believe.

Ответить
@sanphir
@sanphir - 12.01.2024 09:23

You forgot to mention the singleton thread safety

Ответить
@5cover
@5cover - 12.01.2024 09:15

I like Singleton, but too many of them can become a problem

If you've ever done Cities Skylines modding, you'll know that i'm talking about Manager hell.

Colossal has a CitizenManager, PedManager, VehicleManager, BuildingManager....

Having many nounified classes ending in "Manager", "Controller"... is a code smell of bad design that the Singleton pattern enables.

They are sometimes useful, but they should be the exception, not the rule. (i.e. you should only have a handful of them per project)

The reason is that stateful Singletons introduce global state.

Ответить
@robertlenders8755
@robertlenders8755 - 12.01.2024 08:56

To me, the issue is the public static Instance part. In terms of complexity, a public static property that exposes some state may as well be an additional field on every class in your application. It's impossible to tell who or what changed the state of your singleton other than running a debugger. If you have a single instance that's passed into the constructor of every class that actually needs it you've vastly reduced the scope of classes that may use your instance incorrectly.

Ответить
@GameDevNerd
@GameDevNerd - 12.01.2024 07:30

Strongly suspect the guys giving this kind of advice on LinkedIn are what I consider the "most dangerous class" of programmers, lol. It's not a blundering newbie/junior, it's the ones who are close to the next level of the infinite "learning curve" ... they're starting to actually understand stuff, for real, and that point in your journey (after a year or two minimum feeling like you're slogging thru deep mud and constantly confused) is a super rewarding and gratifying moment in a programmer's career ... even the most modest of us will start feeling a little pride/excitement in ourselves and these new skills we've started to learn to flex with, lol. Problem is, they have no idea how much further the learning curve actually goes (forever lol) ... they don't realize how many astronomical units or light years away from an "expert" level they actually are because they still haven't gotten enough experience/exposure to see the whole playing field and understand where their place in it is. By their reckoning, they're damn near an expert already, and wouldn't mind arguing with an expert or two, lol. And that's what makes them dangerous: they don't know what they don't know, and they think what they do know is nearly everything there is to know. So they try to buck trends/convention and challenge orthodoxy/authority on things and try to "prove" stuff to people ... that's how your repos & pipelines get blown up (or nuked) or how your app ends up with a brand new bug somewhere that the code was already _fine_, but they went and fiddled with it on some kick like this guy and singletons, wanted to "show these guys" and be a bad-ass, and they wreck stuff they shouldn't have even been messing with, lol.

If you're a manager or owner/stakeholder, those are the kind of devs to be scared of, lol, not the timid juniors trying to nestle up under a senior's wing ... watch those "mid-level" guys who are starting to gain awareness of design patterns and terminology/jargon ... they're the real risk factor in a critical environment!

As far as singletons go ... I use em modestly when they make sense for sharing a "global" instance/state ... which is typically things like a "just leave it alone, it's fine as-is" sort of solution (esp. small/temporary stuff I don't want us to waste much time on, and of course those "to replace soon" singletons where you know it's not a good long-term solution but will bootstrap this new project up fast), or in some cases it's just an absolute perfect, logical fit ... I think I run into the latter least of all, and when I do it's usually, you guessed it, Unity ... and singletons (at least for `MonoBehaviour`) in Unity are weird ... you can't get at the base class constructors, and aren't supposed to do so because the engine needs to manage scope/lifecycle of managed C# objects tied to Unity engine resources in the native engine libraries (i.e., UnityEngine.Object) ... user code tampering with the hidden constructors and internal lifecycle management can leave ya with "hanging pointers" and mem leaks galore, not to mention you can CTD the whole engine lol. When I work in Unity, I'm not trying to avoid singletons, I'm trying to avoid `MonoBehaviour`, lol, they're expensive and not easy to get rid of when you don't want em anymore, lol. In the old days, we had to write larger-scale Unity games in some very strange ways to maintain steady/smooth frame pacing ... using Linq, any temporary new( )/new[ ] usage in the "hot path" (portions of the app directly in the main game loop) and stuff like that is definitely banned if your game is big and you want it to see the light of day, lol. So you start coming up with strategies to recycle static pre-allocated memory over and over and never new-up any collections or objects per frame ... and it's that per frame part that makes it so deadly, because what seems like a "little" memory leak is scaled by a factor of at least 60x per second ... if you're leaking a mere 256-bytes, for example, you can live with that right? Hold on, that's like 15KB per second ... that's over 900,000KB (almost 1MB) per minute. Your game and all the content probably ate about 2 to 5GB of RAM easily, but I've worked on projects at studios/teams with 60 to 120GB+ builds, some games that will really push your hardware. So you may not have much memory when you start playing ... now you're leaking by the MB per minute ... the player won't be enjoying your game for very long before they come flame you in a Steam review, lol.

Ответить
@rafaelg0225
@rafaelg0225 - 12.01.2024 07:06

I don't now if Nick is diversifying his content, but to engage in this type of argument for a serious developer it's just beneath him, people will say crazy things online and if Nick's intention is to warn newer devs of this, then I guess I can give him the benefit of the doubt.

Ответить
@chswin
@chswin - 12.01.2024 05:45

lol never 😂

Ответить
@tommaple
@tommaple - 12.01.2024 05:42

A good solution for DI-based singleton might be to have 1) a public interface, 2) an internal class (that implements it) and 3) a public method (usually a public extension method in public class) to register the interface and the implementation in container as singleton IN A SEPARATE LIBRARY (library can contain more than just that). With this approach anywhere except for that library, this class can be resolved only via the container and only as a singleton.

Ответить
@xlerb2286
@xlerb2286 - 12.01.2024 04:41

I don't use singletons often but once in awhile they show up. I typically use autofac for DI. I register the type as I would any other type being injected, but mark it as a singleton. If the singleton has dependencies no problem, I just take them in the constructor. Autofac (or any other capable DI framework) will resolve the parameters when the singleton is instantiated. For testing or for customizing of the application it's easy to use a mock or other alternate implementation by overriding the type registration.

Ответить
@yoanashih761
@yoanashih761 - 12.01.2024 04:36

I think the biggest pain for singleton is testing...

Ответить