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

  Рет қаралды 74,716

Nick Chapsas

Nick Chapsas

4 ай бұрын

Use code MICRO20 and get 20% off the brand new "Getting Started with Microservices Architecture" course on Dometrain: dometrain.com/course/getting-...
Become a Patreon and get special perks: / nickchapsas
Hello everybody, I'm Nick, and in this video, I will go through some really bad advice telling you that you shouldn't use the singleton pattern ever in .NET.
Workshops: bit.ly/nickworkshops
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: github.com/Elfocrash
Follow me on Twitter: / nickchapsas
Connect on LinkedIn: / nick-chapsas
Keep coding merch: keepcoding.shop
#csharp #dotnet

Пікірлер: 296
@keesdewit1982
@keesdewit1982 4 ай бұрын
As many patterns, the Singleton pattern is just another tool in my toolbox, and I will use it when I think it is the appropriate tool for my task.
@Alex-gj2uz
@Alex-gj2uz 4 ай бұрын
100 agree, perfectly usefull pattern. Logging is a perfect discipline, period.
@minatoDev
@minatoDev 4 ай бұрын
I would go further and say not as many, but as all patterns are just tools
@NihongoWakannai
@NihongoWakannai 4 ай бұрын
@@minatoDev well some of the patterns people talk about aren't really "tools" so much as common sense that everyone uses always. Whereas a tool is more something that you use in a more specific scenario to solve a specific set of problems.
@timseguine2
@timseguine2 4 ай бұрын
@@Alex-gj2uzI think there are sometimes better alternatives even for Logging, but I think that is a perfectly acceptable use case. In general, I would say cross-cutting concerns such as logging are the places where the "urge to singleton" is the greatest. But I dunno, I tend to think the right tool for that job in a prefect world is Aspect Oriented Programming, which unfortunately is not a very well supported paradigm and not an option for most people (I personally wouldn't really recommend PostSharp for example for reasons which are a bit too long for a youtube comment, and the alternatives in c# are basically zero because of the way Roslyn works for now).
@jemakrol
@jemakrol 4 ай бұрын
Touché. Tools all have their pros and cons.
@adamgardner3364
@adamgardner3364 4 ай бұрын
Using a Singleton (true Singleton or via DI) has the benefit over a static class in that it can implement an interface and thus be mocked out when testing classes that utilize it. In your example, it would let you fake the guid returned and therefore confirm whether those other classes are correctly handling that specific Id.
@TheHegi
@TheHegi 4 ай бұрын
This should have been the focus point of the video. I think Nick completely missed the point with this one.
@LE8271
@LE8271 4 ай бұрын
That is a DI topic isn't it? I do not see how a regular "old-school" singleton would help in mocking.
@svenjohann6078
@svenjohann6078 4 ай бұрын
@@LE8271 If you have a IGameManager defined, noone prevents your from handing it over manually into constuctors. The DI just does that for you. Instead of handing over GameManager.Instance, you could then i.e. hand over GameManagerMock.Instance in your test...
@michaldivismusic
@michaldivismusic 4 ай бұрын
@@LE8271 I've done it with an old school singleton as well. The Instance property was typed as the interface instead of the actual class and the property had a way of setting it via a method. The app would set the regular implementation upon it's start and the tests would set a mock version. It wasn't nice, but it did the job.
@LE8271
@LE8271 4 ай бұрын
@@michaldivismusic I miss something probably so let me learn something new about it. What makes the singleton any different to a regular class then in terms of interfaces and testabilty? Where is the value added during test?
@vargonian
@vargonian 4 ай бұрын
I definitely want to hear more about your thoughts on us going too far with dependency injection in .NET.
@mattkins99
@mattkins99 4 ай бұрын
Years ago we had a problem where recruiters didn’t know how to filter candidates before sending them to us to interview. The problem was if we gave them a list of questions to ask, they didn’t know enough to understand the answers candidates would give. We joked back then to have them ask the candidate if they preferred static or singleton. The answer didn’t matter but if they got angry while answering, send them along to us.
@lordmetzgermeister
@lordmetzgermeister 4 ай бұрын
That's actually a really smart way to deal with the technical deficit of recruiter agencies!
@sqlexp
@sqlexp 4 ай бұрын
You lost the good-tempered candidates and got the ones with anger issues.
@timseguine2
@timseguine2 4 ай бұрын
@@sqlexp They probably are missing some good candidates with the approach. But anger is often a sign of engagement. And engaged developers are something I want. You can filter out the truly choleric people during the interview.
@kevinviera5621
@kevinviera5621 4 ай бұрын
I wouldn't say "if they got angry", but a candidate that does not directly select one of them but tries to make a point about each one.
@awesimo4684
@awesimo4684 3 ай бұрын
Hah, I'm not sure I'd get mad being asked about singleton vs static, but it reminds me of how I get a little perturbed when people start asking about the Heap and the Stack. In my many years of C# programming, the only time I've needed to know about the allocation of memory is in interviews. One of the whole points of .NET is that you don't need to worry about memory allocation! That's the number 1 benefit of managed code!
@jojify
@jojify 4 ай бұрын
Hey, Nick you should create a design pattern course which can explain major design patterns with scenarios
@BigPoleTightHole
@BigPoleTightHole 4 ай бұрын
I think this would be an awesome course for him to create to host on dometrain, because when I first started out this was a tough concept to learn due to the lack of good explanations available.
@Esgarpen
@Esgarpen 4 ай бұрын
@@BigPoleTightHole If he made a series on all the 'big' design patterns, I would join the dometrain
@theanachronism5919
@theanachronism5919 4 ай бұрын
There's a channel called RawCoding who has a large play list of C# design patterns
@NihongoWakannai
@NihongoWakannai 4 ай бұрын
There are already a lot of them, design patterns aren't really something that should be studied hard. Just learn the basics and then start making projects that utilize them so you can get experience on what feels good and what feels bad.
@chrissieinszweidreizweiein2013
@chrissieinszweidreizweiein2013 4 ай бұрын
RefactoringGuru has a great overview of design patterns and examples. Not in video, though.
@vinny6935
@vinny6935 3 ай бұрын
I have unit tests that get the instance of a Singleton and test that its methods do what they claim to. For any behaviors the Singleton does that i want to prevent during unit testing, like connecting to an AWS service, I'm using interceptors. You mentioned them in the video, they are an incredible tool available to us now to make mocks easier and to change pretty much anything. They feel C++ raw pointer level of dangerous if misused, but for testing they are fantastic. As a side note, I've been a developer for almost 40 years and a professional developer for 25, with almost 25 of those being in .NET. I LOVE your videos, it's incredibly important to never stop learning but your videos have been inspiring me to dig into packages I've never heard of and to explore new language features more. Thank you for sharing this content!
@fifty-plus
@fifty-plus 4 ай бұрын
Most hand baked singletons I've seen are poorly coded and not in fact singletons in all cases. Best to use your DI container to manage lifecycle and scope.
@chrismitchell9936
@chrismitchell9936 4 ай бұрын
100% totally agree with you. I use singleton exactly as you propose. Futher..i might use it conditionally..with for example scoping and also with user away injections. some instantiations might poin to the singleton and orhers might point to a different implentation that also is a singleton. other times i point to a true transient.
@zombieguy
@zombieguy 4 ай бұрын
I've honestly just never found another solution to singletons that fits when it comes to games. Unlike most generic software there is so much more branching, benefits to lazy loading and ease of use requirements for other disciplines on the project. Something like "World.Instance.Spawn(Thing.SpaceShip)" can ensure an object is spawned through the game framework (like Unity) and therefore has a managed lifecycle, can be mocked for tests, is accessible from any script and can be lazily loaded.
@jrcscomputing4618
@jrcscomputing4618 4 ай бұрын
Unity itself uses lots of singletons. I use them many times to have a locator service. I use a service locator to find common used objects and scripts. It is very useful and as another user wrote it is just a tool that has its place and to be honest if it works well then for me it is appropriate.
@akaHarvesteR
@akaHarvesteR 4 ай бұрын
I shudder to think of the reference wrangling nightmare I would have if I couldn't use something like GameLogic.LocalPlayer in my code. This is another case of people generally dismissing potentially valid tools just because they failed to think of a scenario where it was the best tool for the job.
@SunSailor
@SunSailor 4 ай бұрын
The service locator pattern is very easy to implement, even in Unity, which tends to defy classic patterns due to its serialization override. You still can have pseudo singletons, which are handled by the locator and not by the runtime as a static. This allows proper unit testing of the singleton service and easy mocking of other services, the service is calling.
@PajakTheBlind
@PajakTheBlind 4 ай бұрын
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.
@happyfarang
@happyfarang 4 ай бұрын
since I started coding there have always been some people claiming singletons are bad. I find it to be snobbish. They work great. I use them when they makes sense. I use static classes when they makes sense (to me). If it works it's great. That's my approach. It's a bit the same with clean code etc. Sure, if you are in a big team, there have to be rules, but for me, as a lonely solo dev, I feel no shame when I make a singleton. lol.
@viniciusmendonca7727
@viniciusmendonca7727 4 ай бұрын
What I like most in these videos is that I learn something I didn't want to and now I have to watch the rest of the video just to "unlearn" it again
@petedavis7970
@petedavis7970 3 ай бұрын
Somewhat related, I've recently started wrapping some static classes and some methods with services. For example, File and Directory, as well as static DateTime methods. The reason is that if you use these directly in your code, it makes unit testing difficult/impossible. By wrapping them in a service, I'm able to DI the service and thus the classes that use them can now be tested. And usually the service closely matches the static class and calls the static class directly. I want to say that you covered something similar in a past video (wouldn't be surprising with the volume of videos you release), with regards to DateTime.
@chrismingay6005
@chrismingay6005 4 ай бұрын
I think it's sound advice. You've got to ask yourself if the code's so good, why is it still single?
@tomchapman128
@tomchapman128 4 ай бұрын
It gives my compiler warnings.
@jeffwilson8246
@jeffwilson8246 4 ай бұрын
Because it got a divorce... Duuuhhhhhhh
@7th_CAV_Trooper
@7th_CAV_Trooper 4 ай бұрын
Because it got caught observing other classes.
@user-dg9wh9bx2x
@user-dg9wh9bx2x 4 ай бұрын
Red flags raised by lint
@arielspalter7425
@arielspalter7425 4 ай бұрын
lol
@calebvaccaro
@calebvaccaro 4 ай бұрын
This the most Unity video without mentioning it and I’m here for it.
@user-hb7py7xy7b
@user-hb7py7xy7b 4 ай бұрын
For me singleton is a go to pattern for services with long connection/startup time, which methods are used frequently.
@xardasu3646
@xardasu3646 4 ай бұрын
I use singleton pattern when having to use httpclient and that instanceof htttpclient needs to maintain its connection accross multiple upload file request.
@ADreamPainter
@ADreamPainter 3 ай бұрын
For me, I use singletons to manage different elements of a game's state, or contain useful functions that all classes can benefit from accessing. For example, I often will have an audio manager. The audio manager can do things like play sound effects. It can also keep track of the current song. This opens up possibilities such as having music cross fades. Or it can control the master volume levels. Another example is for network communication. The singleton holds information about the current network settings, and which server it is talking to. In order to do server call, classes can call the network manager to send data through the network. The network manager also routes incoming messages to the appropriate player. Finally, for a game I built from scratch, I had a screen manager. The screen manager could adjust the resolution of the game. I also set it to be in charge of rendering everything. All graphical elements had to send a render command to the screen manager. The screen manager would handle the sorting order of what needed to be rendered in what order, so elements would overlap properly.
@superior5129
@superior5129 4 ай бұрын
Since you talked about how C# is focusing more on functional programming I'd like to see more videos about this subject. I'm currently using alot of RxNet and you have Schedulers there which are mostly singletons. I really recommend seeing how fun is programming with RxNet.
@TastyMysteryMeat
@TastyMysteryMeat 4 ай бұрын
I'd love to see your take on Dependency Injection and it's possible overuse in C#.
@nocturne6320
@nocturne6320 4 ай бұрын
I think this advice might be coming from the Unity game engine community. The way Unity (and pretty much all other game engines) are designed is terrible for keeping clean code. Since you don't control when will what object/script be instantiated and none of the game engines offer a dependency injection functionality, you are sort of forced into using Singletons in some shape or form
@rhysvanderwaerden5518
@rhysvanderwaerden5518 4 ай бұрын
Almost all unity developers use Singletons in some form, so why would the unity community advise against using them?
@happyfarang
@happyfarang 4 ай бұрын
to be fair to the game engines, that is only a half truth. All the code you make that is not a game object works normal. Singletons works fine in unity. There are just many people who bitch about them in the unity community :)
@peteruelimaa4973
@peteruelimaa4973 4 ай бұрын
Because game-code needs to be fast and Clean Code(tm) is usually slow.
@FurryDanOriginal
@FurryDanOriginal 4 ай бұрын
I actually was recently told by one of my workmates that in university they were told that singletons are an anti-pattern so I assume this opinion is more widespread than just within the game engine community.
@zwatotem
@zwatotem 4 ай бұрын
Or you can do, what the advice conveys and pass everything down
@FromBeaverton
@FromBeaverton 4 ай бұрын
Thank you, Nick! Code with singletons is long-term maintainable. I inherited a non-customer-facing project with dozens of singletons, and, after initial shock, I found that it is indeed a very descent poor-man solution. Singletons for anything other than top-level business logic manager are perhaps a bad design, but it is slightly bad, not terribly bad. I do not understand the argument that singleton is equivalent of static class. I want to watch that person implementing an interface for a static class. (you might want your singleton to implement an interface if you need to pass it to a third-party library which requires it)
@Rafloka
@Rafloka 4 ай бұрын
I really appreciate your non-dogmatic approach to these topics!
@neverlandhomie
@neverlandhomie 4 ай бұрын
I do not know if already some states this but statemachines and sheduler are pretty common use case for singletons. In general I would say, anything that holds a application wide state can be a singleton.
@xlerb2286
@xlerb2286 4 ай бұрын
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.
@brianviktor8212
@brianviktor8212 3 ай бұрын
There were cases where I had to use Singletons. Generally I avoid them, but in Unity it's hard to avoid. I also happen to have created code for Singletons, from which classes can inherit from, and the instances can be accessed by the "Instance" property.
@benjamininkorea7016
@benjamininkorea7016 4 ай бұрын
Don't use singleton? How else will I get one user's personal data to fill itself in on another user's text inputs? So unfun.
@TheWolverine1984
@TheWolverine1984 4 ай бұрын
The issue with singletons is that they are often abused as data dumps to get easy access to information that bypassed the DI mechanism. (Or in applications where DI isn't used at all). And then you end up with functions or classes where it isn't obvious what they require to do their job. You might find a line like `singleton.Instance().ObjecA.ObjectB.ObjectC.Counter++;` I agree with the roasted advice that you should prefer to inject dependencies via the constructor with DI. Though in this case if you pass `ObjectA` in the constructor, the problem would remain.
@MMMM-vc5oi
@MMMM-vc5oi 3 ай бұрын
Nick, I believe that if we utilize DI frameworks, we can do away with the need for singleton classes altogether. For example, in the GameManager class, we can define it like a normal class and then inject it into other classes as a singleton instance. I use zenject DI framework in Unity3d over the past several years and I am happy
@colindawson4818
@colindawson4818 4 ай бұрын
It’s a tool in the box. I don’t typically use it, just like I don’t typically use the GOTO command, having it available and knowing the power that it can bring to the table might, just might help with solving a specific problem. Just because I haven’t used it in a long time, doesn’t mean that it’s bad to use, or that there’s always a better solution. Everything has its time to shine, and to dogmatically deny its usefulness is akin to tying your hands behind your back.
@Spirch
@Spirch 4 ай бұрын
at 5:50, it is thread safe, the line that does = new Singleton() will be converted into static constructor in IL and this should be thread safe, let me know if i am wrong please
@TheTigerus
@TheTigerus 4 ай бұрын
Isn't singleton the most common type of service in dependency injection?
@johndenver8907
@johndenver8907 4 ай бұрын
Great video as always. I've often given the advice that you shouldn't use static classes. But they have their place too, just if you are beginner try not to use them as they will often seem easy and powerful while making refactor harder later. This is mostly as you say because of IoC being a thing. For reasons of making your code easier to change and test. When something is supposed to be singleton make a factory or configure the IoC. Adding stuff to the class to signal your intentions is good. Like make the constructor private or something, but there are lots of ways of doing it and sometimes it's how you use it now how it's made.
@kmcdo
@kmcdo 4 ай бұрын
Engagement’d! Also, I want the “DI has gone too far” take
@eugene3685
@eugene3685 4 ай бұрын
As always, any powerful tool should be used wisely. DI is good, but in some rare cases it may be a bad idea to separate type functionality and its instantiation (DI). And to say it's a terrible pattern is too much. This sounds like my own advice at 16, after 1 month of coding.
@phizc
@phizc 4 ай бұрын
All WPF and WinUI3 apps use singleton. The App class has a static Application Current property that holds the instance. Probably all XAML apps, but I havent used MAUI, Xamarin Forms, or Avalonia, and its been too long since I've looked at Silverlight to know for sure..
@SingletonSean
@SingletonSean 4 ай бұрын
Love this series Nick! I might have to create a reaction video for this one 😄
@tommaple
@tommaple 4 ай бұрын
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.
@badwolf01
@badwolf01 4 ай бұрын
I've come to find that articles, comments, or posts that call something an anti-pattern are trash - more likely than not. Everything is an anti-pattern when used incorrectly.
@dzllz
@dzllz 4 ай бұрын
Excellent video. Would love more vids about DI.
@erikgrundy
@erikgrundy 4 ай бұрын
i think there is something to be said about the whole 'global variable' thing. In multi-threaded contexts, a singleton is often a big bundle of shared mutable state you need to handle with care. Even when that isn't an issue, a poorly implemented singleton can make you unsure of your program's state, because you're not sure where the state gets updated. Not to say that they're never useful, but that you should be thoughtful about when you use them, what parts of your code can see them, and how to properly abstract the state they hold.
@evezero9834
@evezero9834 3 ай бұрын
I think a singleton should never expose any writeable state. Because in this case you just introduce a global variable.
@guiorgy
@guiorgy 4 ай бұрын
I thought some of the key advantages of a Singleton over a static object, are that (assuming it isn't statically instantiated inside) it can be lazily (when needed) instantiated instead of at startup, especially if the object is heavy to instantiate, or the memory could be saved if the object may or may not be used (created), or it can be initialized with a state that is not known at compile time.
@thomaseb97
@thomaseb97 4 ай бұрын
if you want lazy instanciation singleton is not the way, there is already a type called Lazy
@thomaseb97
@thomaseb97 4 ай бұрын
an alternative to lazy is factory method pattern, which could accomplish a similar goal
@ElCerdoBlanco
@ElCerdoBlanco 4 ай бұрын
​@@thomaseb97 of course you can lazy-initialize singleton instances. In fact, I almost always implement them this way. I usually register most of my classes to a DI container and once a specific class is required, all the other required instances are either re-used (if they are singletons) or instantiated. And if they are no longer required, they are disposed - so there is no need to manually handle the lifetime of the instances any more.
@eusouodouglas5730
@eusouodouglas5730 4 ай бұрын
I understand this guy, the legacy code I manage has a lot of singletons for business entities that should be stateless so as we can't have properties and manage the state of the business entity the code in the end has a lot of huge methods that are a complete s#it to manage and they in some cases the previous developers had to add locks to entities that could be stateless. The result is that we have an application that was fast when the application had 5 consumers and now with more than 100 I'm facing a lot of semaphore conditions affecting calls that are not related... So I understand that singletons are for cases where stateless approaches can be replaced to save some processing/io/etc
@billy65bob
@billy65bob 4 ай бұрын
Most of the time when I use Singletons, it's because i have a magic 'empty' or 'default' value. For example, If have a class for identifying resources (e.g. images) by a Guid, I'll add a special 'Empty' singleton that just wraps Guid.Empty, so I can use that as a default value instead of null.
@jupahe6448
@jupahe6448 4 ай бұрын
I was thinking about the same thing more or less, but that's not exactly a Singleton you can and are expected to still create other instances of a class don't think there's a name for it but I would just call it magic references
@PbPomper
@PbPomper 4 ай бұрын
Why not just instantiate it as Guid.Empty? Or use it as a fallback in your getter.
@piaIy
@piaIy 4 ай бұрын
​@@jupahe6448 it's called the null object pattern
@michaelkhalsa
@michaelkhalsa 4 ай бұрын
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.
@JacobNax
@JacobNax 4 ай бұрын
It really depends. Singletons in general can produce un-intended side effects if the end user aggregates the software's logic into a bunch of singletons. It all depends on the use case. In most use cases you want to use them to access a global instance for some very specific non-generic reason.
@Beacher1085
@Beacher1085 4 ай бұрын
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
@ErazerPT
@ErazerPT 4 ай бұрын
Sounds like the "new GOTO". People regurgitating something they heard about without knowing or understanding the context.
@klocugh12
@klocugh12 4 ай бұрын
If you can add setInstance to singleton, what exactly would stop you from setting instance in utility class, possibly even worse, as side effect of some random utility method? Also singletons are not necessarily global. You can make them internal. And they literally encapsulate the sole instance, so that didn't make sense either.
@dusrdev
@dusrdev 4 ай бұрын
You mentioned thread-safety, is the version you created thread-safe?
@mjohnstone2399
@mjohnstone2399 4 ай бұрын
I use Singletons for COM Interop @7:39 having a static property won't work in my scenario as the type library compiler will not compile static members.
@youngthinker3447
@youngthinker3447 4 ай бұрын
Singleton pattern is a great way to manage application configuration, while you are working with microservices and you have common configuration required in all microservices, worst part is it will not allow to change configuration once the singleton class instance is created, but here also we can have a pub-sub mechanism to recreate the singleton instance , if we change the common configuration
@davestorm6718
@davestorm6718 4 ай бұрын
That's the best part: not allow to change config. I only use it for this purpose as well (config).
@TheCMajor9th
@TheCMajor9th 4 ай бұрын
glad ppl still value singletons , which i still use as they come in certain scenarios very handy
@sean109
@sean109 4 ай бұрын
@nickchapsas Yes, I would love to hear why you believe we are overdoing dependency injection in .NET. 12:58
@zwatotem
@zwatotem 4 ай бұрын
I didn't exactly understand, how is it different to keep classes' state in static fields/properties vs in an Instance static property. For me it seems exactly the same, except there is one extra step when using the singleton's Instance property. Otherwise the state of that object is equally as available (e.i. equally as global) and I can read and modify it from anywhere. If static fields were conceptually meant for unchangeable values, then it was at least poorly conveyed. I never heard of it anyway, but if that's actually the case, they should then be immutable by default. In short I sympathize with the author of the post, in that if you want to have a global state, you're better of just using static properties for that, but generally just don't. Still, DI container is a useful and versatile enough tool, that it'll fulfill most of your needs, including instantiating a class once, while not locking yourself up from loosening up that single-instance constraint if that ever happens to be the requirement of your application.
@sirsamtheman
@sirsamtheman 4 ай бұрын
One advantage of a singleton over a static class is that a singleton can implement an interface or extend another class. Which can be useful in some scenarios.
@heliobessonirodrigues6632
@heliobessonirodrigues6632 4 ай бұрын
I think he was talking about web (multi user/tenant) applications, where a global state doesn't make any sense (only in the database). And I think this is another problem, singletons shouldn't hold state. For unit tests it is a nightmare if it does IO. For your example, a game, a singleton is useful since it is only used by a local single user/process, but can be refactored into an object tree, like a react component, where you only have one root component but it is not a singleton.
@lupf5689
@lupf5689 4 ай бұрын
Even in a web application a singleton might make a lot of sense to provide read only runtime data or as a shared cache across multiple threads / requests.
@AlexMason81
@AlexMason81 4 ай бұрын
Good breakdown Nick. I would enjoy hearing your thoughts on the overuse of DI.
@nik6823
@nik6823 2 ай бұрын
any idea about dotnet 8 interceptors yet? 12:22
@omarjuul
@omarjuul 4 ай бұрын
@nickchapsas why would the example not be thread-safe? As far as I can tell it's perfectly thread-safe because of the way static constructors are called in .net. What am I missing?
@user-hb7py7xy7b
@user-hb7py7xy7b 4 ай бұрын
I'm pretty sure Lazy is thread-safe. Example in video is not thread-safe. Easiest way to correct this is to implement readonly property and use lock check. Jon Skeet "C# in Depth" has a good chapter regarding Singleton.
@charles_kuperus
@charles_kuperus 4 ай бұрын
Nick Please let us know what your view is on why we or taking dependency injection too far in dotnet?
@FarukLuki111
@FarukLuki111 4 ай бұрын
When I saw this on LinkedIn I KNEW you would make a video 😂😂
@nickbarton3191
@nickbarton3191 4 ай бұрын
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.
@user-no7hv1om2x
@user-no7hv1om2x 4 ай бұрын
TBH I'd prefer not to use Singletons at all, and instead allow the DI to manage the lifetime. Why? - maintainability - sometimes there is a need to convert a singleton into a n-gleton, or a scoped lifetime service. Not so easy with the classic implementation. - testability - how to test the singleton itself? implement a Reset() method? That beats the point doesn't it - spaghetti code - it's been mentioned at the end but I feel this topic hasn't been explored enough here. While it's true that the classic impl prevents multiple instantiation, it opens up another pandora box - the shared state... Why not add this other class instance here just for future reference? Why not also add some caching? Oh, and make it thread safe why you're at it... and suddenly all your SRP code goes away. I've seen it happen and it happens more often then one might think. I'm not the author of this advice but I'm generally against singletons in the classic sense, at least in web apps where they can be avoided. No idea about Unity though.
@madner201
@madner201 4 ай бұрын
Feels like just about everything .NET has its place. Figuring out how to efficiently and effectively use all these constructs generally improves understanding of the platform and use cases for its components.
@sentzeu
@sentzeu 3 ай бұрын
I’ve yet to find a use case for them when working in .NET and writing web services. Maybe if I was rolling mt own Dependency Injection framework, or Cache structure, but there is no need to.
@robertlenders8755
@robertlenders8755 4 ай бұрын
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.
@ElCerdoBlanco
@ElCerdoBlanco 4 ай бұрын
That's true, although actually not a problem of the Singleton pattern but the reason for Inversion of Control.
@sepdronseptadron
@sepdronseptadron 4 ай бұрын
While I agree with most of the things that you said, I think you're missing what they want to say here They're not saying that the idea of a single state is bad, they're saying the way that you implement that single state using a singleton is bad for example, the GameManager, if you make the list static and all of the methods static, I'd be the same as a singleton class My opinion on this is that it seems like a subjective thing to argue about, because both methods is the same except for a bit of some style difference in how you access that single state ex. GameManager.CreateNewGame() vs GameManager.Instance.CreateNewGame()
@bosegeorge1425
@bosegeorge1425 4 ай бұрын
Please start having a subscription plan too. Buying each course is lot i believe.
@dovh49
@dovh49 4 ай бұрын
Yes, let's hear what you have to say about DI!
@andreyandreev4636
@andreyandreev4636 4 ай бұрын
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
@lordicemaniac
@lordicemaniac 4 ай бұрын
Main problem with singletons created through DI that do not prevent you from creating them once is that they are same looking as any other class. If you design your code with specific class as singleton and then some other colleague needs to update that class and use some dependency, if he just inject that dependency through constructor, the singleton will keep that dependency forever and that instance will not change ever. This may create problem where that instance should be single use for example some kind of builder. Any best practice how to avoid this?
@Thial92
@Thial92 4 ай бұрын
That's why Scoped and Transient exist too. Not to mention the mediator pattern which removes dependencies.
@mnmr
@mnmr 4 ай бұрын
Every single service in our DI setup is a singleton (albeit some are factories for producing instances of something else).
@TalicZealot
@TalicZealot 4 ай бұрын
Even old school AOC containers used Singletons for lifetime management. Ninject had SingletonScope and RequestScope, which Microsoft now gives us by default.
@F1nalspace
@F1nalspace 4 ай бұрын
Nothing new for me, except for the builder. Can we use this microsoft builder thing in normal .NET applications, such as console and UI applications (e.g. WPF, WinForms, Maui)? What are the advantages over other IOC containers, such as DevExpress ServiceContainer?
@othmaneg99
@othmaneg99 4 ай бұрын
you can use the builder in a console , it just doesn"t come built it you have to add a few lines to your program.cs
@user-we6wp1ky7f
@user-we6wp1ky7f 4 ай бұрын
One question about the singleton in the video. I think if each time we call it’s Instance property we will get the new instance of a class, or I missed something?
@user-we6wp1ky7f
@user-we6wp1ky7f 4 ай бұрын
I am wrong here cause the instance property is static.
@TehGM
@TehGM 4 ай бұрын
I am mostly against singletons. That's cause, as other comments say, they are usually poorly written, without any maintainability and testability taken into account. Especially prevalent among Unity devs. However - each pattern/anti-pattern is just a tool/thumb rule. Saying "absolutely never use it, ever" goes against that. And singleton-lifetime services are just a must in any practical application.
@MysticAngel3224
@MysticAngel3224 4 ай бұрын
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.
@nayanchoudhary4353
@nayanchoudhary4353 4 ай бұрын
Apart from inconvenient use of Shims in UTs, this is a useful design pattern.
@pyfferoenc
@pyfferoenc 4 ай бұрын
The biggest problem I face with singletons is in testing, all the tests use the same instance and then conflict
@mattkins99
@mattkins99 4 ай бұрын
Make your constructor and the static instance field internal and then make internals visible to your test project. Parallel tests using the singleton as a resource can still cause problems but honestly most of the time I define the class as a singleton in my DI framework and then testing is no longer a problem at all as I pass my mock in as I please. Static is worse and honestly the only way I’ve found to make code testable that relies on a lot of static objects is to replace the methods in static classes with functions that I can replace for tests. In my test initialize method I “backup” the original function. In my test I replace it with whatever I need, then I restore the function from the backup in the TestCleanup method. Annoying and doesn’t allow for parallel tests… but sometimes you gotta do what you gotta do.
@hoppy6437
@hoppy6437 3 ай бұрын
For testability, I would just ensure the return type is a public interface. If I was a really nice guy, I would add a second static method GetStub, so the developer doesn't even have to write it. Also: Use you need to deal with race conditions on that instance.
@Wobling
@Wobling 4 ай бұрын
+1 for a video on "DI has gone too far"
@smokinglife8980
@smokinglife8980 4 ай бұрын
I use them for managers like in the video but that is about it i don't see a valid use of singletons for anything other than a manager of some sort
@dbohdan
@dbohdan 4 ай бұрын
Very interesting video, but I couldn't resist the urge to update the Rider
@Kabbinj
@Kabbinj 4 ай бұрын
Do not mix together the singleton the design pattern with singleton the lifecycle type. Sure, a singleton design pattern object will have the singleton lifecycle type, but they are two separate concepts. And it's not the enforcement of single instance that is the common critique for singletons (although I'd argue it's not the object itself that should have this responsibility), it's the static access to the instance that is critiqued, foro to how it almost invites abuse. I'd very much agree with any advice against singletons with public getters.
@Naton
@Naton 4 ай бұрын
I use it to store struct constants
@akademiacybersowa
@akademiacybersowa 4 ай бұрын
Bottom line is that application HAS to have some static global data. At the bare minimum it has to have it's own instance. Religiously avoiding globals like singletons can cause issues as you need entry points for data, and passing some find of execution context into all functions that MIGHT need them is just counterproductive for many, if not most, cases. Also (01:40) singleton by definition can have only one instance at once - not during whole lifetime of the application. But to be honest, it's about having a single point of entry in form of static global reference/pointer getter, maybe with added lazy initialization inside. So in fact we can have many instances created but only one is exposed at any specific time via this static global reference.
@Steven-ch2wm
@Steven-ch2wm 4 ай бұрын
The LinkedIn post focuses solely on the Singleton Design Pattern, while you talk a great deal on the Dependency Injection concept Singleton lifestyle. As far as I see, the LinkedIn post, how skewed it might be, doesn't refer to the Singleton lifestyle and, apart from the name and ensuring a single instance (within a certain context), there is little similarity between the two concepts. It, therefore, feels like a straw man argument that you're mixing the two and criticizing the author on something they didn't write. Because of their naming, developers sometimes confuse one concept over the other. Perhaps that’s the reason you talk about the Singleton lifestyle? If that’s the case, it would be good to state that the original author didn’t mention the Singleton lifestyle, but you’re showing it anyway to prevent confusion with any of your viewers.
@jz5153
@jz5153 4 ай бұрын
I mean the only valid comment that could be made here is why and when would you like "classic" singleton over just regular class that lifecycle is manage by DI container.
@timseguine2
@timseguine2 4 ай бұрын
The problem with singletons is: Singletons imply an awful lot of additional things about the entire system they are used in you probably don't actually want but might not notice for a long time (or ever). And once you have problems with them, they are almost impossible to remove. On the other hand, sometimes (often, really) the bad things they imply never end up being a huge issue. There is a bit of a cargo cult around repeating advice without knowing the reasons, but a lot of people will tell you not to use singletons because they have been bitten by them badly in their own code or code they have worked on. They are like a cute little stray puppy, where it looks like it could either be a husky-mix or a wolf, but you're not sure which. We're just trying to tell you it might work out fine (and in many cases it will), but it isn't worth getting your face bitten off in your sleep just so you can adopt the cute little puppy.
@Dacusx
@Dacusx 4 ай бұрын
Anything, such as "goto," can be used if done responsibly, and only when really needed. Also, "singletons" have their place. For example to fast prototype something.
@pharoah327
@pharoah327 2 ай бұрын
In game development, we use Singleton a good bit. Never had any issues
@qj0n
@qj0n 4 ай бұрын
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
@erikf790
@erikf790 4 ай бұрын
It’s true that people repeat this advice and follow it blindly. BUT, the original anti-pattern advice on this was to not use the single PATTERN, not to not use singletons in general, which can be implemented in many useful ways that are not problematic (as shown in this video). This advice was only ever meant to refer to the original Gang of Four singleton pattern, whose use had become so commonplace that this advice was created, much like the advice to never use goto’s. Just as there are legit reasons to use goto’s the same is true of the singleton pattern, and like goto’s there are also better constructs that work the same way that achieve the same results. The original don’t use singleton pattern advice was associated with three problems, global state, thread safety and testability. The singleton pattern is problematic in all these ways, which is why the advice was given. For the vast majority of developers, “never use the singleton pattern” is good advice, the just aren’t experienced enough to use it safely.
@marcusmajarra
@marcusmajarra 4 ай бұрын
I think that my biggest argument against Singleton as a design pattern is that it's difficult to control the lifetime of the Singleton instance. It's easy to accidentally introduce code that might instantiate the Singleton prematurely, which can be a problem if the Singleton or another consumer of the Singleton expects a particular state. This is why I tend to favor DI containers as a mechanism to restrict instance counts. In most cases, consumers don't care how many instances of a particular dependency exist. Their contract doesn't revolve around that. But the DI container allows me to retain control over the order of object construction, and allows me to enforce a singleton state over a particular class without having to design the class for it. Now, if you want to know which popular design pattern I find easiest to abuse, I would go with Observer, particularly in the context of parallel programming. When you have a bunch of observers listening to a subject for a particular change, each ready to spawn separate threads to perform other work, debugging subjects becomes a real pain as it becomes more and more difficult to track just how far the dominoes are toppling.
@mrwalkan
@mrwalkan 4 ай бұрын
How static keyword really works?
@tandjebantje4460
@tandjebantje4460 4 ай бұрын
Found the LinkedIn profile that posted it and gotta say, I am not surprised he was posting shit like this.
@digibrett
@digibrett 4 ай бұрын
Please do expand on how MS is going too far with DI.
@local9
@local9 4 ай бұрын
static vs singleton is not some I'd ever consider, they both have their reasons, and I use them for those reasons, I've mostly been against poor use of each.
@pseudohyena
@pseudohyena 4 ай бұрын
Singleton has two parts: 1) It ensures only one instance can be created, 2) It provides a global access to the class. When you think you need a Singleton - you usually need only one part of it, the first one. The second, on the other hand is the reason why a lot of people consider it an anti-pattern. Singleton (global) managers tend to create perverse incentives that lead to spaghetti code without a structure and clear flow of logic. Because why think about structure of the code architecture, about domains, their scopes and responsibilities, when you have a global manager that you can access anywhere in the code? (And sometimes those managers access other similar managers...) There are legit reasons to have a manager that is instanced only ones, but the way you access it shouldn't be via Singleton, there are better ways to do it, ways, for example, that ensure this specific type of managers can be accessed only in a specific context. Sometimes you can use Singleton here and there I guess, but you really should avoid it as much as possible. From what I've seen Singletons in the project can quicky escalate into a terrible mess, especially when a junior developer uses them.
@Bravo-oo9vd
@Bravo-oo9vd 4 ай бұрын
You're exactly right, sometimes there are valid reasons for wanting to ensure that there is only one instance of a class, but then 2) global access to the class makes you design your entire system around this global access, and if after some time you discover that maybe you actually want multiple instances of a certain object for any reason, then all of a sudden it's hard to refactor sensibly.
@justindoyle8091
@justindoyle8091 2 ай бұрын
Eh, I kind of agree that singletons are essentially another form of global variable. Immutable singletons are fine, the same way global constants are fine. But I've always thought the best thing about singletons is that they're easy to remove when you realise you shouldn't have used the singleton pattern. Because you're already passing around the instance of it right? And not just calling Singleton.Instance whenever you want? Right? I think it's really dangerous to be able to change the state of a single object from anywhere in the code which is why we don't like global variables any more. I guess it's ok if the singleton is stateful as long as it's completely in control of it's own state after creation? Logging for example. After you set it up you don't directly modify the state. You send it messages, it does its thing. It might be keeping track of things internally, which rolling log file we're up to or whatever, but the rest of your code doesn't care and can't influence that directly, so you can treat it as an immutable object. Side note: I really dislike utility classes too. There could be _anything_ in those things. Extension methods are fine. They're static, but equivalent to adding a method to a class you otherwise wouldn't be able to extend.
@PajakTheBlind
@PajakTheBlind 4 ай бұрын
I'm down for criticism and overuse of DI
"Stop Using null, Use default Instead in C#" | Code Cop #010
7:06
Nick Chapsas
Рет қаралды 63 М.
"Stop Using Async Await in .NET to Save Threads" | Code Cop #018
14:05
Did you find it?! 🤔✨✍️ #funnyart
00:11
Artistomg
Рет қаралды 113 МЛН
Uma Ki Super Power To Dekho 😂
00:15
Uma Bai
Рет қаралды 55 МЛН
Каха с волосами
01:00
К-Media
Рет қаралды 6 МЛН
"Stop Using Properties in C#, Just Use Fields" | Code Cop #013
11:53
What Is .NET Aspire? The Insane Future of .NET!
18:35
Nick Chapsas
Рет қаралды 255 М.
Swagger is Going Away in .NET 9!
10:48
Nick Chapsas
Рет қаралды 64 М.
delegate in C# | How it Works
27:33
TechBuddy EN
Рет қаралды 429
Why You Shouldn't Nest Your Code
8:30
CodeAesthetic
Рет қаралды 2,5 МЛН
"Don't Use Loops, They Are Slow! Do This Instead" | Code Cop #011
9:51
5 Rules For DTOs
17:56
Ardalis
Рет қаралды 35 М.
The .NET 8 Auth Changes You Must Know About!
10:27
Nick Chapsas
Рет қаралды 129 М.
6 INSANE Things You Didn't Know You Could Write in C#
12:26
Nick Chapsas
Рет қаралды 50 М.
Why Do C# Developers Hate The var Keyword?
11:15
Nick Chapsas
Рет қаралды 60 М.
Did you find it?! 🤔✨✍️ #funnyart
00:11
Artistomg
Рет қаралды 113 МЛН