BrandGhost

How to implement facade patterns in .NET C#

This video is part of a series where we will explore how to create a facade in C#. We will be using a repository as a basis for our facade and then exploring some of the challenges and benefits. Our facade will be composed of multiple plugin sources where we will use Autofac to load them in dynamically at runtime. When you're done with this video, you should follow up with this one: https://www.youtube.com/watch?v=-pxwL_VD4Uo Want the source for this video? Check it out here: https://github.co...
View Transcript
today I'm going to be focused on plug-in loading and how I like using something called the facade pattern in almost all of the applications that I try to build we're going to be building in C sharp today and using a nuget package called autofack let's jump over to visual studio alright so I am back in Visual Studio here I'm just going to get a console app created so we have a project here brand new console application and I mentioned I want to be talking about something that I call the facade pattern I didn't coin the term I didn't invent it but it's just something that I use heavily and I talk about plug-in systems a lot because a lot of how I design software applications is really about almost having like a skeleton framework as the core app and then pushing out a lot of dependency specific code into plugins then I dynamically load those at runtime and I can put them behind something called a facade that will do the right thing for us the facade itself is a a class that we will Implement and it adheres to an interface and as a caller of the facade you don't actually need to know that if it's a facade in fact that's the point it's sort of masquerading as something that performs some tasks for you and actually behind the scenes we have loaded plugins that do different things have maybe different implementations we're going to be going through an example that has different sources of data or object creation so we're going to check that out today and that happens behind the scenes of the facade and as the caller you don't need to know that's happening and it keeps it nice and transparent to you one of the the things that I really like about this pattern is that it lets us design applications without having to think about the details behind the scenes and uh and then we can actually extend these applications with more functionality a lot of the time without having to break apart existing parts of the code code base sometimes we can just drop in whole new dlls and dynamically load those plugins and have that functionality sort of get dropped in which is super cool I've I've definitely seen criticisms to this type of approach too like when people go debugging things when you're not expecting to come across something like a facade because it's a level of indirection and can sort of split from like one class that you might be expecting into you know it's uh it's sort of this interface across potentially multiple instances of different implementations if you have a bug somewhere and that's kind of the point that you get to as you're debugging it you might go oh crap I totally wasn't expecting that I'm gonna have to go now check out like you know 10 different variations of what I thought was one type of implementation so definitely a criticism of it but I personally like having the separation and if I go implementing tests and things and I can test um the individual implementations as necessary and then maybe do some type of functional testing over you know the set of loaded plugins as well to to ensure that they adhere to the right patterns and uh and expectations so that's a super high level idea of what I mean by facades and the types of plugins uh and and that kind of loading that we're going to be looking at today and I'm going to dive into um kind of an example here that's a bit of an evolution for me um because as I said I build a lot of systems with plug-in loading and more recently I kind of feel that I found a pattern that I'm kind of happy with so um let's let's talk about the facade and sort of implementations we're going to look at today I want to keep it super simple because a lot of the time when I do something like this I might be building out dependency specific implementations so for example if we had a facade for a repository pattern I might have a plug in with an implementation that's loading from a sqlite database and then I want a plugin that's able to load from maybe it's also a sqlite implementation but another sqlite database and perhaps I have a whole second completely different implementation of that plug-in meets the same interface and everything but it's going to be connecting to a you know a MySQL server um and pulling data from from that as a repository so that's generally how I end up seeing this kind of stuff in my own in my own work but we're gonna we're gonna skip that part I don't wanna spend time connecting to databases um setting all that kind of stuff up it kind of isn't really relevant for the parts that I want to talk about today I end up finding myself saying okay like let's use a repository patterns we're going to talk about a facade that is going to wrap multiple repositories but they're just going to be in memory um simple repositories that wrap a uh like a very I don't know simple object for us so let's let's talk about that object might look like call it my object super easy actually let's use a record we'll have some property on the record okay and then we're going to start by having an in-memory implementation of a repository so what we'll do is um we might do like a private read-only I read only collection of my object look at that autocomplete it just know knows what I want we'll Implement a method that's something like I enumerable get all objects okay and just to give you another example when I have repository patterns like this I might pass in something like a a filtering context or something and then allow the repositories to do adequate filtering so I could Implement that in SQL or sqlite or you know in some document database store and I could have that specific to the implementation so in this case it's in memory if we wanted filtering I could do something like link or something like that but we're going to skip that it's just going to return the objects that we pass in so what we might do and we'll show this with loading with auto fact is that perhaps we have different dlls where we allow someone to create an a repository so we'll have an interface for it and they can drop in those repository implementations when these are created they'll have a set of objects behind them so let's go ahead and pull this out this other file over here cool so what does the facade actually look like gonna be very similar to what we're looking at already so you might be going this is kind of dumb but once we start actually populating some data in here and calling it you might see some of the benefits so my object repository facade and we are going to let it Implement an i Repository and actually when we get a little bit further ahead I'm going to change some of these interfaces around show you how I've been implementing it up to this point and actually uh a bit of a change to that pattern that I'm really happy about and because I use it the same way and basically all of my projects it seems like a nice refactor that I can go leverage and clean some stuff up that pattern may not work well for you you might not want to do that in your applications that's totally cool there's so many different ways to do all of this kind of stuff and I feel like if you're watching anyone making content or people you work with anytime someone's saying there's only one right way or like one way is always wrong um I think that's incorrect there's pros and cons to every decision we make and I think that what I'm about to describe works well for me if it doesn't for you that's totally cool let's hear about it in the comments right we're gonna take in a collection of eye repositories okay so it's going to wrap a bunch of repositories we pass in the collection of repositories and again this method is going to look very similar to the one above except instead of going over the list of objects we are going to ask all of the repositories we're going to use Link here just to keep it simple quick check at what we're doing here this facade still implements this I Repository but when we construct it it's allowed to take in more repositories and it doesn't care about the implementation so this is a key part here we're just using the same interface it's going to ask because it's a facade hiding the complexity here it's going to ask every Repository hey um what objects do you have and then it's just going to slap them all together in an innumerable for us and pass that back to the caller let's go ahead let's pull these out okay so now we just have our program and you'll see that I'm going to say I want to we're going to do this on auto fact in just a moment so we would new up a um my object repository facade and I'm gonna put this in here first and we're going to extract it into dedicated plugins and show how that loading mechanism works with auto fact but I want to show you how it looks before I do that refactor so you have a better understanding if you're not already familiar with autofac and how we can take advantage of this setup so each repository takes in let's do one repository where we have um the names have letters in them and then the second repository they're going to have numbers in them okay so that's one repository and then maybe we have a second one like I said which would be numbers what we'll do is we'll show how to set this up in Auto fact have these pulled out into different assemblies load it all up if you check when I hover over this I mean I should do this this is how it will look when we start using it from Auto fact it's just going to be an irepository rate when we call this and it has get all objects if you're just looking at it from this perspective the fact that it's an i repository we can't tell that it's a facade because we're only caring that it has this interface on it so we don't know about the implementation obviously we do because we're looking at this line above but if you were to have this somewhere else and someone's call and get all objects on an i repository facade or not you don't know that's the point that's the beauty of it if we run this okay so obviously you're not printing anything out but if I were to hover over this in super small text if you can't see because I don't think I can zoom in on this bottom portion if I go to all objects results view you can see or maybe not squint a little bit but I have six objects here with the letters first and then the numbers after so the facade did its job it aggregated all the data for us beautiful now let's do the next step and start pulling this into Auto fact but that's going to be a conversation for the next video so if you have any thoughts questions or concerns about what you've seen so far with facade patterns please let me know in the comments and I'm happy to get back to you and have a conversation about it so if you thought this video was useful please give it a thumbs up subscribe to the channel and of course like I said we'll put this next video up here for you to see or maybe over here

Frequently Asked Questions

What is the facade pattern and how is it used in .NET applications?

The facade pattern is a design pattern that provides a simplified interface to a complex system. In .NET applications, I use it to create a core app that dynamically loads plugins at runtime, allowing me to separate dependency-specific code from the main application logic. This way, the caller interacts with a facade that hides the complexity of the underlying implementations.

What are the benefits of using the facade pattern?

One of the main benefits of using the facade pattern is that it allows me to design applications without worrying about the details of the underlying implementations. This separation makes it easier to extend functionality by adding new plugins without modifying existing code. Additionally, it helps in testing individual implementations while keeping the overall architecture clean.

Are there any criticisms of the facade pattern?

Yes, one criticism is that it introduces a level of indirection, which can complicate debugging. When a bug occurs, it might require checking multiple implementations behind the facade, which can be unexpected. However, I find the separation beneficial for maintaining and testing the code, as it allows for more modular and flexible designs.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload