 Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and with me is Phil Jepixi. Hey, Phil. How are you? Good. Good. We are well into our series on design patterns. We are. And in the previous episodes, we covered the behavioral patterns. We did. And we are now going to talk about the creational patterns. Yes. So let's just review the difference between the two. Sure, sure. And it just occurred to me we probably should have done this at the beginning of the series. Sorry about that. So there's really, when you break it down academically, the gang of four who founded really first documented all the design patterns and whatnot, there's three categories. Behavioral, creational, and structural. So we covered the behavioral. We didn't talk about really what that meant. But it just deals with the responsibilities and communication between objects. So for example, the command, the strategy pattern, all those shows that we've done so far. Creational, exactly like it sounds, deals with making things. Making things, right? We've said several times, new is glue. We don't want to use or create something and then use it in the same method, not really even the same class. So this gives us some ways of creating things, especially when we get into the factory, so we don't have to do that. The final bucket, if you will, is structural. And that deals with the composition and relation. So we're going to talk about many of these patterns. So we're going to talk about all of these. The adapter, decorator, and facade. And again, those are just the three main buckets. We started off with the behavioral, not because I thought they were more important, but because B comes before C, which comes before S. So that was the order that we chose for the different buckets. Okay, so today we're going to talk about the singleton pattern. Yes, we are. Okay. So the singleton pattern is used in many other patterns. Just as the command pattern is used all over the place, we find these things blending together, right? So we're going to talk about the factory patterns next, and you'll see that the single pattern, a lot of times is used to create those factory objects, because we only need one of them, right? Yep. So many DI frameworks, for example, have- Dependency injection. It's right, yes, Dependency injection frameworks provide singleton support. Think of ASP.NET Core and a Dependency injection built into there. I can create something scoped at the singleton level. Okay. That means that across that entire web application, regardless of who's coming in, there's only one instance of that object, right? So would your navigation be a singleton then in an app? So to be honest, I very rarely will use navigation as a singleton. Okay. Just because that can be static, right? It doesn't matter how many. All right, so let's talk about this. They're static and they're singleton, and they seem roughly the same, but as is very well documented, well, I will say thoroughly documented because I've read the explanation of why they're different, and I'm not a C sharp deep dive expert. There are some differences. Static classes are not guaranteed to be thread safe. Okay. Which means you can get more than one instance in an app domain if you just make them static. Okay. People ask me why all the time. I've got a link to the article. We'll put it in the show notes. It has to do with a lot of things that honestly as a line of business developer, I don't go down that deep. Okay. If Microsoft says not thread safe, I say, okay, and I believe them. And I do it differently. All right. If we're tracking something, for example, let's say you're selling ad space on your website and you have to know how many unique visitors there are. That's a good candidate for a singleton object across your entire website because it doesn't matter if I'm hitting your website, if you're hitting your website, if Bill is hitting your website, you wanna know how many visitors across the board. And you wanna make sure you're only counting it once and that you're not splitting up multiple instances because then you'd be losing revenue. Got it. Okay. One thing not to put into a singleton is, for example, a DB context from an AD framework. A lot of times people think that's a good candidate for a singleton because creating a DB context is fairly expensive. I mean, there's a lot of ramp up that goes including creating connections, checking the database to make sure that it matches the schema that an AD framework expects, but the problem with making it a singleton is the DB change tracking. So every time I pull something into an AD framework, I start tracking it, right? But you have the same instance of the DB context. Now you're change tracking and my change tracking are interfering with each other and can cause really weird side effects. So whereas it seems like a good candidate for a singleton because of the expensive operation, it's not because having one globally shared instance of a context in the framework is a bad idea. Okay. So we have to really think about the use cases. Right. All right. So there are some conventions and we did cover this pattern in the mega talk, the solid design patterns from the mortals that we did, but like all the other patterns we covered, we really zipped right through them. Right. So this will give us a little bit more time to talk about it and answer some questions. You can usually recognize a singleton by a static property named instance as shown on lines 24 and 25. There's no requirement for that at just the way people do it. Like... It's a good... It is a good pattern. It's a good pattern because it tells you right then and there. Yeah. And I guess I shouldn't have used pattern. Practice. It's a good practice. Just like naming your interfaces with an I. Yes. Right. So we know that it's interface. Right. So I am declaring two different variables, both pointing to the instance, static property of my singleton class. So it's a singleton class. It is designed to be declared once those should be the same. Yeah. So in X unit, and this is the same for the other frameworks as well, equal and same are two different tests. Right. Equals looking at a value compare. Same is, are these both pointing to the same thing? Right. Like the same object on the heap. And line 26 is just verifying that they are the exact same object. I have just an arbitrary integer property on my singleton class. I increased the value on the first variable. Mm-hmm. And then I confirmed that those values between the two variables are still the same. I increased the value on the second, and I do the same. So all this test is proving is that we are, yes, indeed, pointing at exactly the same object across the entire, at least this unit test, right? We're not proving different. Users are coming in differently. Right. But we can count on that working the same way. Okay. Let's look at how to implement it. And we'll start off with my singleton class. Lots of comments in here. And the reason I have comments in here, memory leaks, threading issues, they're very hard to prove or disprove. So I prefer to stand on the shoulders of giants. There's great documentation on MSDN about how to do singleton and how not to do singleton. Okay. Like we were just saying before, why static doesn't work exactly what we wanted to. I'm not sure that I care. I care that it doesn't. So I know not to do it, but the comments and the links in here will point you if you are so obligated to go dive down. And again, the GitHub repo will be in the show notes. We haven't said that on every episode, but it will be. IDisposable is not part of the singleton pattern. It's just to have it I like to get into, to make things that might have expensive resources implement IDisposable. So we have a private static of my singleton class. Again, just by convention, we call it instance. We have a object by convention. We just call sync lock. Okay. Here's the key. The class itself has a private constructor. Okay. So nobody outside of itself can construct a new one. And we seal it to prevent anybody from deriving and changing that behavior. In general, sealing a class is probably considered a code smell. There's lots of classes in the .NET framework, at least the full .NET framework that we're sealed, which made unit testing very, very hard. So in general, like I said, it's kind of a code smell, but for the singleton, it's very important that you seal it. So nobody derives from it. Things they have a singleton whereas they really don't. Right, okay. And here's the magic. Here's how they make the sausage. So I have a public property called instance. Again, just a convention doesn't have to be called instance. It's a good one though. So if the instance is null, this is that private variable. If it's not null, I go ahead and return it. I say, okay, we have one created already. Here you go. You can use that. If it's already been created. If it's already been created. Okay. So in C sharp six, we had a fix to static properties by using the volatile declaration. We were talking about before we got on the air. Wait, did you just say volatile showed up in C sharp six? Yeah, according to my notes. Oh, okay. We were talking about this before for the viewers. Hope you liked a little banter that Robert and I do on the shows. It seems they've gone well in the past. I couldn't remember what version volatile showed up in. So it wasn't six. And then I go right down here and it says removed a block because this is fixed in C sharp six. Okay. Now volatile might have been there before C sharp six, but it didn't work right. Ah, okay. So we're gonna go with that. Because I'm not gonna take the time while we're recording to research when it came. Yeah, it doesn't really matter. There is a volatile keyword. The volatile keyword and in C sharp six and later it works as expected. Okay. The volatile keyword as the comment declares ensures that the instantiation is complete before it can be accessed further, helping with red safety. Okay. Now, how does this play into the whole mix? Let's go back to our instance. Right here, we're not locking. We're not doing anything. We're saying if the instance is created, here you go, have at it. Line 42 is locking this block. This means it's only single threaded. We don't lock outside of line 42 because we want them to be able to get to line 40 multi-threaded if the instance is already created. We don't wanna hold them up with arbitrary single threadedness. Prior to the volatile fix in C sharp six, we would have to add another lock on line 46 to make sure that the instance was created. But if we back up and look at line 44, if the instance is null, right? So even if I have multiple things coming through and hitting line 42, only one of them gets through. Okay. Instance is null. Goes down, creates a new instance of the Singleton class. We've got the volatile keyword on it, which then means that it won't move on until it's completely instantiated. Okay. And then on line 49 we return the instance. Yep. When we get to line 49, the next request gets released by the lock, comes in, sees that instance is not null, pops right out, returns the instance. Right. So the only ones that are held up are the ones that came in at the same time or before the instance was completely instantiated. Okay. And then the rest of that is just a class. Okay. I have values, I have properties, I can have methods, I can do everything else. It's good practice to implement iDisposable. That's not really a design pattern, it's just something we should do in C-sharp to clean up after ourselves. So we can take a moment to talk about that. When something is marked for garbage collection has been disposed. And I'm not gonna, I'm sure you've had shows on garbage collection and how all that works, so I'm not gonna go into deep details about that. I'm sure there have been shows on garbage collection. So what we want to do is, if we know that we're done with a particular resource, we wanna go ahead and dispose of it so that the garbage collection happens earlier. There's different generations of garbage collection and lots of magic behind the scenes as to when.net clears memory, but we wanna be the good citizen and recycle as soon as possible, put it in the blue bin. We did it with the iDisposable, so then we can call dispose. And in the dispose method, again, plenty of comments here, again, not a design pattern, but something that's good to do. So I just figured since this is a short episode on the single 10, we'll fill it with some other good information for cleaner codes. If dispose is called, then we tell the garbage collector, nope, we've already been disposed, please don't call us again. Okay. And then here in the dispose method, anything that is expensive, we would just set to null. So if we've got in full dotnet framework, if we've got pointers or if we've got connections to the database, things like that, we would release them. Okay. So there's not a whole lot to talk about that either. If you follow the instructions that are in the comments of the code, it all works out for you magically. So again, Singleton is when you have a class and you need to ensure that it only gets instantiated or created once. Yes. And that the entire global world, at least that app domain has access to that. Because you can't create more than one, so it better be global access to the one. Yes. Otherwise you're in trouble. Right. All right. Cool. Thanks. All right. Hope you enjoyed that one and we'll see you next time on Visual Studio Toolbox. Thank you very much.