Dependency Injection

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi welcome to visual studio tool box I'm your host Robert Greene and on today's episode we're gonna talk about dependency injection and what better person to have on the show to do that then Miguel Castro then the guy that still talks about the penalty that's right that's right so we're gonna talk about what is dependency injection how do you do it but more importantly why should you do it oops now aren't am i doing it already and not knowing it if I'm not doing it why should I be doing it what's what and what problem does it solve well it solves two primary problems okay it solves testability and dependency resolving and the two one can exist without the other but by implementing the fantasy injection in the right way you've conquered two things you've killed two birds with one stone and you can do one or the other and you're halfway there but you're still missing something so by getting full-blown in the BI you're you're making applications testable and you're you're making the ability to resolve dependencies down what can be a complex object graph significantly easier and instantiation of dependencies is not something trivial it's very easy to say I'll just knew something up if I need something right but that's why we make classes but first of all by newing something up inside a class method you're already making the class untestable because you're causing a couple a coupling there that probably should not be there your hard coding the newing of something from something else and that's something we want to avoid that's one of the things that dependency injection helps you remedy also when you tell somebody stop doing stuff up you better sure as heck have a alternative for them because that's a pretty shocking off statement if you eventually have to exactly exactly but all you're doing is that you're offloading that responsibility to something else that something is it is the product that helps us with dependency injection dependency injection itself is not a product a dependency injection container is a product di is an architectural design pattern and it solves these two things testability and resolving it solves resolving through the help of the container it solves testability because in order to do di correctly you have to learn how to embrace abstractions and how to embrace abstract classes out to interfaces right and that helps you with the testing so you see how the two can exist without the other but the overlap is significant to where it's a match made in heaven for those two things and the sad thing is you know we started out the conversation by me jokingly saying I'm the guy that's still talking about it and I speak at a lot of conferences and I do these kind of talks at conferences and I get a lot of good feedback and then I got a lot of feedback from more advanced developers that asked me why am I still talking about this we've been doing this for the last ten years everybody's doing it let me tell you something heads one of the biggest it is and I'm and it's everybody's doing it turns out I wish I did he things not everybody yeah I wish I didn't have to be talking about it but I fill the room up when I talk about di at a conference like today's conference I fill the room up completely with people that just have not used it at all or not using it enough or it's not mainstream in their everyday development and and they don't realize just how much it can help you out and how much it can remedy things but you know better things for you in your applications and you know when I start bringing five people into the room when I do this session maybe then I'll stop talking about it but until then there's still too many people out there for whom this has not become mainstream and it really does need to be okay it's too good to pass up and it's very cool and done the right way there's a coolness element and with everything we do in code it has a coolest element it just makes it all so much worthwhile you know so let's see let's see how to do it alright alright so I got this demo broken out into three different stages okay and the first stage is gonna be the problem stage this is without the problem being solved whatsoever okay so what I'm gonna show you here is that I'm going to show you a hosting class this is the class that my UI this is my UI right here okay my my console app and in stage one which is the one we're gonna do first of course my main class is called a commerce class and the commerce class its job is just to process an order okay and the order is contained in this one data object that you see here order info which you're looking at at the top just has some arbitrary information this is not my real credit card number I just want to make sure there's nobody taking notes right now and but that is my real email address where people can notify me if they like or hate what they're saying here okay and as you can see we're doing something that's completely ordinary we're Steinke instantiating the commerce class into a variable and we're processing an order doesn't get simpler than that let's dive into the commerce class a little and see what's going on in there now I've broken out in the interest of separation and concerns I've broken out the stuff that the commerce class is doing into three different subclasses just so I can have some reusability and some code manageability so that's not really part of what we're doing here to solve the problem but this is something I don't expect everybody to do anyway the building processor the customer processor and the notifier the job of the building processor is to process your credit card the job of the customer processor is to update the database with the fact that you've now purchased these products and the notifier sends you out a receipt simple enough no big deal now if I run this right now all of these things are just going to show something in the console app nothing nothing major no I am not processing anybody's credit card nor am i sending out any emails but there's a reason that I mentioned that because what if I was is you can see here says payment processed that customer processor is calling another class yep I'm gonna show you that it's calling a data repository and it's calling a product repository to update the inventory that's what you see their purchase saved and inventory updated then the customer record is finally updated and then the receipt is sent so you see what's taking place here now if I go into that customer processor class simple class but as you can see that class is instantiated to other classes so already I've shown you two problems that I don't know if you've seen yet the customer repository is just doing something very simple but it can just as well be doing something more complex in reality that customer repository is going update the database the product repository is gonna update the database where's the problem here this customer processor is hard coding the instantiation of these two classes so number one how am I going to test this how am I going to write a unit test two unit test the update customer order without hitting that database the answer is I'm not without hitting the date without hitting the database how am I going to do that without making any code changes I can't there is no abstraction taking place here the instantiation of these objects create a mock customer repository I've gone I can eventually do that but I got to change some code in the way this application is written right now and sadly there's just a lot of stuff that's written this way that's the testing part let's go up one level back up to the commerce class and talk about that testing again how am I going to unit test process order without being locked into whatever these classes are doing you know local DB or Express now you're talking about pointing to a different let's just change the connection that's strange yeah but you're not that's not really a I don't wouldn't consider that a good idea that's not what I would want to do I don't want to hit any database I mean in a true unit test in an integration test maybe in a unit test that's really not the job of the unit test that's way too large of a unit you're doing way too many things so there's a lot of stuff taking place here so this in this doesn't impede testing overall testing but it impedes unit testing mostly Unitarian you can't isolate the unit's right the individual thing going on exactly right you're having a hard time isolating the units okay um is the screen on yeah oh okay all right so that's the number one thing that's going on I mean I imagine running a unit test where I'm processing the credit card in the unit test which is what I'm doing here when I'm updating our database I don't unit tests I don't have to do dependency injection right that's my out you know as much as most people would agree that that's the solution of the problem I'm not gonna even attempt to dignify that unit testing has to be done look not none of us not all of us really enjoy writing tests and I'm not I'm I'm not the biggest lover of in tests but I acknowledge the fact that they need to be done it's like exception handling right we don't want to do it exception handling at some point has to be beyond slash lash to do right you know you got it you got to take care of it somehow they somehow making the user happy is something that you have to do so we have two problems here number one if we want it to unit test this weekend's number two if we wanted to introduce another dependency it's a matter of going into the level that we have to go into and instantiating that new dependency thus adding to the completed problem of unit testing right so we're just furthering the problem so that's stage one so let's fix one of these problems first let's concentrate on the unit testing problem okay we concentrate on the unit testing problem by abstracting classes to interfaces now I have my other folder here now make sure that all this code is available to your viewers but in this commerce class in this in the stage two folder here notice well I'm gonna I'm not going to open that up yet for a reason but I'm going to start by showing you the new building processor now the new building processor as you can see it's abstracted to an interface I billing processor okay the customer processor it's abstracted to an interface called I customer processor now the customer processor receives in the let me open this up in the constructor two arguments for the dependencies that we're injecting into it this is the architectural design pattern are the code design pattern of dependency injection without the use of a container yet we haven't gotten there yet but we distract it out and we've injected the dependencies into whatever class is going to use them so we've made our classes testable because now we're given the code the customer processor the option of what kind of customer repository implementation is going to use in the case of production it's going to use the real one that accesses the database in the case of a test we may actually either have a test class that does something else that we want to do or more efficiently we would use a mocking tool to mock up a test class which is what most people do today okay okay the repositories same thing if I go to the customer repository it's abstracted to an interface so everything is obstructed to it interface so we have that nice abstraction that we're embracing and we've decoupled one class from another one in one implementation from another by depending only on definitions which of course is defined by interfaces okay so now without getting into a unit test how do we instantiate commerce now I'm looking at commerce here we see that commerce I don't know I have no idea why it's been doing this recently yeah yeah yeah I can I can close it down and open it up and we're fine okay so take a look at the commerce class we see that it requires three dependencies just to be nude up if I go into one of those dependencies like customer processor we know that it requires two dependency yes so now the newing process has gotten a little more complicated we've eliminated the problem from the classes itself but now we have to we've relocated that problem is what we've done right if I go over to my where do you create ah well let's open up stage two and see what happens now doesn't this look beautiful I was being totally sarcastic by the way that's good totally sarcastic B looks harder it does C I don't understand what well and again being and it gets by the line of code oh it gets even harder and I see what happens is that we've made these classes fully testable which is really good news but by doing so we've introduced the problem of dependency resolving now because we can solve the problem like this but notice that commerce is being instantiated with new instantiations of building processor customer processor and notifier and customer processor needs the instantiation of its dependencies customer and product repositories so it looks like a mess so if we did this here what have we gained if we stopped here yeah we've gained testability because that's it's because we abstract it to interfaces it can now not rely on the hard coded implementation of these interfaces in testing as well as production levels this is production right now but if I wanted to test the billing processor I'm sorry the customer processor let's go over to the customer processor I can unit test this class now I can unit ace unit test this method by instantiating this class from a unit test and sending into it something other than the real customer repository and the real product repository would have to have written somewhere or give mocking or you mock it most people would say that you mock it that's what I would tend to agree with there are situations where you have a set of test classes in a set of production classes so previously back in the billing processor if I wanted to test that well building processor in our example building processor does not have case any dependencies is it which is the first one that calls what calls customer process Commerce is it commerce right here okay if you wanted a test process order right now you'd have to mock billing processor customer processor and notifier and in the process of mocking customer processor you would have to mock its dependencies right now that's not going to change going forward with what we're going to do because we solve the testing problem and we've given it to the testing guys if they happen to be a different team if they're a different team it's awesome because we can go get a drink if it's us which more often than not it's going to be the same guys we've at least given ourselves the ability to do it we haven't gotten to the next part yet but now we can test now that the job of testing is the job onto itself writing unit test is as much of an art as writing code so either way in stage 1 or stage 2 I have to have two different versions of each of the processes well in stage one you don't have that choice stage one you're locked in stage one I'd have to create you're locked in billing processor and that's it because it's being created for you inside the hosting class right so here I still might create the test billing processor but I only have to create it at the very highest level I don't have to dive down into everywhere it's called to switch from the real billing processor to the test billing processor is that right no you if you're if you're going to create a mock of billing process or you only need to do it if you're going to unit test a class a class methods that needs that dependency okay only I mean if I'm unit testing building processor let's look at the billing processor class itself well if I'm unit testing this particular class it's got no it's got no dependencies and this particular implementation is probably going to call a payment gateway and process a credit card so that's not something I would run from a unit test but if I were to if I were to process I were to unit test customer processor it's relying on customer repository and product repository so I need to mock these up just to instantiate this class from a unit test alright and and if I'm going to instantiate Commerce I need to mock up its dependencies okay my apologies no worries okay so this first example we've eliminated one of the two problems we've made our code testable but like I said we if you're if you're if you're hung up on the complexity of the unit tests unit tests are complex they can be complex there's no doubt about it and calling a class and sending a bunch of mocks into it you got to know how to do that but that's just the art and the task of writing unit tests that's not going to go away but introducing that necessity for us is a good thing not a bad thing with step one we didn't have the necessity of doing all of that because we couldn't test right so we couldn't do it and that's a bad thing so yeah we got less work to do but down the line we have probably caused other problems for ourselves okay so by writing by me being able to test this and calling this a testable class that's the key thing but here's the here's here's where it gets more complex what now I got the other problem dependency resolved what if I wanted to do something else inside billing process it's inside commerce or how about inside customer process or what if I wanted to introduce another dependency sounds easy enough do the same thing write another let's say another repository write the repository I've strapped it to an interface send in the interface to this constructor and then use it down in the method right right sounds simple enough but now what about instantiating something to fill that argument now we have to start backtracking and what calls customer processor okay what calls customer processor commerce does so now we got okay where's it getting accentuated well it's not accentuated here because we did a good job of abstracting so what calls commerce and we start going up they'll up the chain yeah and we get up to the point where we instantiated commerce right and obviously if we have another dependency something has to be inserted here yep and this is just one simple app example that I put together for this for this webinar imagine this being a full-blown app where this happens five layers deep where it happens in 17 different locations all over the place this yet to be a code management nightmare right it really can so that is where the next problem gets solved by introducing something called a bi container dependency injection container it's also known as a inversion of control container dependency injection is kind of a derivative of inversion of control and version of control is a concept dependency injection is a type of inversion of control there's several other types of inversion of control put simply as simply it's just giving the responsibility of control of instantiation control of one class from one actor to another okay in this case our actor is the DI container okay I like calling it a DI container unfortunately we have now Reese reached a point in software development where the word container has been yet again overloading some will tell you well we've been calling it a container for 20 years yeah but as Microsoft people we really didn't care because I was just Linux stuff right sure but now container is dominated by products like docker right specifically docker because that's what Visual Studio interacts with so what do we do do we refer to this as something else I don't think that's going to happen so I just call it a DI container just can't use more words so we're dealing with the DI container here for a DI container I want to show you that the same abstractions are used so I'm going to open up stage 3 here and show you that the commerce class looks exactly the same the customer the customer processor looks exactly the same yeah there's my interface look at my customer repository we've done exactly I just took taken all that abstraction and moved it okay now what I've done is that I've added a DI container to this project I use a container called auto FAC to me it's the most not only the most part one of the most powerful ones but it's also very very easy to use it was written with a later dot net framework so it's pretty modern this is not product push your product placement you use the container that you like with containers like mocking tools once you learn how to work with one they all do kind of the same thing just let you choose the syntax that you like or the ones that maybe your teammate advise you to use there's a lot of great ones out there Castle Windsor structure map and inject unity by Microsoft hell even meth has some container capability even though it's not typically uses as a DI container not anymore but I just happen to like Auto fact because it doesn't just the DI container know it's a DI container and all of those that I mentioned are also di can yes yes they're not plug-in frameworks like methods right meth has di container capability as a byproduct of its plug-in architecture but it's not typically used for Dia it can be and I have been known to do so but I'm - I typically use Auto fact now just because I like it and it's what I know I can program model fact with my eyes closed I just know everything that it can do but the truth is these container the guys that wrote these things are very competitive with one another you can get out of fact it's just an extension it's just a nougat package that's all it is all of these containers and nougat packages and we'll talk about this a little more later but but for these containers to work with certain dotnet ancillary products like WCF MVC web api those things there are some assistance needed to let the auto fact containers interact well with those products and there's NuGet packages out there for this kind of stuff there is a WCF extensions for auto fact there's a web api extensions on MVC extensions all sorts of fun stuff and there's a lot of there's a big ecosystem or on all of these so people have written additional contributions theirs can trip X projects things like that so I have added Auto fact to up to this project and what I'm gonna do I already showed you the classes the classes look exactly the same but what I'm gonna do now is show you how the instantiation looks a little different it looks like there's a lot more code here but I'm going to talk about this for a couple of minutes okay so when you deal with a DI container you're dealing with two primary things are and are not the RNR that you and I would like to take with our lives but register registry and resolve okay Oh di di containers will take care of all of the instantiation for you but in order to be able to do that they need to be made aware of the classes with which they're going to be working and the interfaces with which those classes are associated so what I've done here is register everything that I need now okay these leanness once you'll do this one so it's exactly right zoom ibly in in a desktop application this will happen in the famous splash screen right in a web application this will happen in the global ASAS okay so yes you do this once this doesn't have to be done anymore there's various ways of registering using any container including Auto fast what you're looking at here is procedural registration meaning I do it in code there is a way to do this with configs as well basically doing here correct me if I'm wrong but you're saying that anytime you see and I okay so now you're jumping ahead a little bit let me do let me that's a what let's start let's start at line 71 which is the first one okay here I am registering the commerce class and I am NOT associating it with any abstraction there is no interface for the commerce class in this particular case okay it probably should be but there isn't but I wanted to give you different possibilities here if you're registering a class or an interface it means that somewhere down the line something is going to ask the container for that huh okay in the case of concur classes like Commerce where they have no association with an interface some containers don't require them to be registered only if they use interfaces some containers do God knows why Auto fact does unity does also okay but stuff like ninja for example does not so you're seeing me register the commerce class here and all I'm doing is telling the container somewhere in the future you may see something asked you for this class so I know about it all right now the second one I'm registering a single class called notifier yeah and I'm saying associate this class with the I notifier interface this means that when something and I'm haven't gotten to what that something is and when something along its Ella in your application somewhere asks you for the an I notifier resolve I want you to new up the notifier class and give me that okay so that's that's I think the part that you know can trip you up because you look in the code and everything is in interface but we're at some point you gotta and you have to new up in instance of right you'll notify my class but this is where you don't code this is where this is where you do these are instructions exactly right handed off the dependency injection the DI containers job the control has been inverted I exactly reverted so when I see I notifier oh I know what to do I need to new I need a new up notify that is exactly right if I wanted to use a different notifier I just changed this single it's exactly right and everywhere in my entire opposition any time I'm using I notify you're gonna get another one you use whatever's here and it's exactly right that's cool okay now I've just read to Singh P I registered one class online 72 yeah notifier two I notifier I need to do this for billing processor I need to do it for customer process right but I don't want to waste time doing it manually because in my example I only had two classes new process exactly and that's what I did here is just show you a way there's a coolness factor here and how cool is this could lambdas are like the coolest thing in the world land I love Landers lambdas are one of those things that hit you like a rock like you you don't get them you don't get them you don't get them and one day poof you get a moment of clarity and you can deal with lambis all I'm doing here is saying scan this assembly for any class that ends with the word processor where I add it to it where my name is chase ends with stage 3 because remember I've given you three examples this is just for my example brings up an interesting question scan the assembly so does it happen each time it start up this happened at one time it's the ones at Build know it start up when this application first runs ok so there is a some what of an increase in startup time it's probably not noticeable it could be I've never noticed it but yes if you want if you want to count computing cycles absolutely of course there is it's like but it's all about returning value right it's like reflection and by the way there's gonna be a lot of reflection you not really noticeable if you and if you do things right the value that you get back it completely mitigates the start of time so I'm saying find me everything that ends with a processor class in my stage 3 namespace and associate it with the interface that is of the same name but starts with the letter I write that's all that little magic is there yeah and this will take care of prot of handling the building and customer processor this will take care of the customer and product repository I do this this technique with for example controllers because if you have a convention you can do this stuff and everybody should have conventions with you model yeah absolutely view models views controllers in WCF clients everything ends with the word client at least like my convention so yes long as you have a naming convention which I strongly feel all teams should have good naming conventions that they're following and they should be well-defined yeah and if they're well-defined it's easy to tell what a class is doing just by what it's named so that's what I've done here I've registered everything and now in the next in line 86 I'm building the container ok excuse me so this is where it's gonna scan through the code and nope nope it's not it's not gonna touch the code it's just building a key value pair list a bucket list if you will I sounds kind of morbid a just a bucket of key value pairs that's all I'm doing here no all the processes and repositories are young well where they are no we haven't gotten to that point okay it just knows it knows the classes are there obviously they resolve in the compiler right so it just is just standing by and waiting now auto fat gives us two classes to do this with one of them is the Builder class which you're seeing in use and then the other one is the container class which is a result of calling the build method every container is different a lot of them have a build right off the container class so it's not a two-step process it's no big deal it's just the way the container was done now I have it's a typical practice is to make the container application scoped so as you can see I've put it into the program class in a static variable which means if I need it anywhere throughout my application I can just call program container this for people that don't like static variables and say that well we don't need them in web applications you're absolutely wrong because when I'll show you later an NBC example an NBC when I create my container I do it with a helper method that the auto fact WNBC integration package gives me if you look at the back of the code behind the scenes of that it's actually putting the container in an application variable okay so it is holding on to it all right because it's gonna need it so when builder dot build runs is that when it finds customer process or customer repository nope that doesn't happen yet nope all that's doing is building this a registration list that's it okay that's absolutely right that's up so that's all it's doing now here is when that so then the upfront time is less than its minimal it isn't it's not actually now looking through your code for every single time you call it that's correct from a process that's correct it does that at runtime it does that at runtime and only for what you execution and it gets to them a gift that exact and depending on what you ask for it I know what you okay here in line what line is that line eighty eight I am instantiating the commerce class right but I'm doing it very differently instead of saying new commerce where I am forced to provide implementations of all those arguments as many levels down in the object graph as are necessary and I got to know about all that I simply as long as my registrations are right are done right all I'm doing is saying hey container go give me a commerce class okay that's all it's doing that's all I'm asking for very very easy as you can see compare that to this gorgeous indentation nightmare here okay and this is much much lighter yeah lighter to the eye that point container dot resolve that goes against commerce that says oh well I need these a damn here's here's where to go fine here's where the beauty starts here's where the magic of di starts and I'm gonna I'm going to put this out there before somebody starts yelling at the screen there is reflection involved in dependency injection all these containers work using reflection I say that because there's a lot of people think it's bad I think reflection is an incredibly powerful tool are there extra cycles involved in reflecting absolutely there is but there's extra cycles involved in setting one variable to another so it's it all comes back to the value that you're getting the return on the investment there's a lot of people out there that are really really anal about not using raw I hate reflection I can't use it because the application slows down well you tell me how it slows down because I don't think my eye complaint is taking longer updates because it's harder to test exactly right exactly right exactly right performance is and I think it was my buddy my buddy bill Vaughn who you know very well said this to me a long time ago that performance is probably the most important thing in your application he was talking about the performance he developers mm-hmm and that's absolutely right it really is now the comment the commerce class here hasn't changed but let me explain what the process it when I when that program class told when I when I asked the container to resolve the commerce class what happens here is a recursion dream it really is what it does is that it doesn't instantiate commerce yet it reflects into the constructor of commerce and sees if it has any interface based arguments the minute of finds one it reflects into that one see is a construct the constructor has any and it keeps doing that down the object graph until it finds a constructor that doesn't have any dependencies now it knows it can instantiate this class and where does it instantiate it what is it accentuate by going to the containers registration lists looking for that interface and saying what class is this associated with ah new this up plug it into that argument or get it ready on standby because it's going to go up the chain now and if it has to resolve more it does so if not if this class is now ready to resolve it instantiates that sending in the instantiation that it just made the previous time and it keeps doing that all the way up till it gets up to the commerce class by the time it's ready to instantiate the commerce class the container already has an instance of whatever class is associated with i billing process in which in our case was the billing processor class whatever class is associated with this and whatever class is associated with the next one right and it injects all three of those instantiations into commerce and when it injects the customer processor if it resolves that prior to this so by the time it has something to inject right here it's taken care of making sure that these dependencies are resolved right cool so that's how we solve the resolving process now just when you think it can't get cooler let me show you something I had this other class here it's called lager yes it's gonna audit trail something so it'll log something to a log file or whatever right work where in my system can I use a class like this now just a side note do you do you have the interface in the same file as the class for readability or is that typically what you would don't no no it's completely readability okay that's just I don't have to waste time here in front of you guys and I know complete I'd have it in a different folder called abstractions or something like I in fact a lot of this stuff would probably be in another assembly so this class where would a class like this be usable in your application there's only one answer to that question everywhere everywhere wouldn't it be exactly right everywhere so what if I want it to do the following what if I want it to go to customer repository and log something right here mm-hmm what would I have to do I would have to do this shoot this is uh I don't think code Russia's installed properly here okay so I'm going to this is the only code I'm going to write I'm going to add a constructor here and I would need to probably expand the scope right okay now that I did that oops I can go ahead and use the logger class here right I'm only gonna do this in one spot but I can do this anywhere in my application at any level just by adding it to the constructor of something right and again it's easy to change the logging mechanism maybe you have five different types you want to test maybe for development purposes you just want to write to the output window production you want to do something different but I haven't done anything I haven't told the container yet that it needs to know about logger I'm gonna do that right here I'm just simply gonna say that's why you'd call it processor and take it out you can absolutely that's purty thats perfect that i totally leave ibly late I totally can do that I totally can do that but good that means you're paying attention that means you're paying attention and that's it no I just registered lager at multiple lagers customer lager billing lager then at that point you probably have different you'd use that bigger scope there yeah okay but do you have one longer here right here I just have one lager which is more often than not what I'm gonna be how I'm gonna be designing an application and as you can see all I did was two levels into my object graph remember it up started at Commerce from Commerce who went to customer processor customer processor went to customer repository and here I'm saying this is customer apposite or lager now I'm gonna go ahead and run the application and let's see if that log takes place three there we go where is it there it is right there there it is this is customer puzzles or lager so if lager was already registered that's this step right here once it is registered anywhere that I want to use it all I have to do is inject that dependency you see the terminology rearing its head yeah that's all I have to do is inject I can put this anywhere that I want and just use it as simple as that it will take care of instantiating it for me the fact that I don't need to backtrack that imagine if we were in this stage right here imagine if we were there what would I have to do to get lager working in customer repository I would now need line 60 new stage 2 customer repository would now have to have inside their new logger exactly and I have to do that in a lot of different parts of the application so I think the value of it is kind of very present in your face now the last example that I have here is an MVC application this MVC application has a simple controller and this controller is using a class here called customer service a customer repository customer repository is simply getting a list of people very important people as you can see yes and it's just returning it so imagine that it's just going out to the database for this right as you can see customer repository is abstracted to an interface yep and if I look at that interface it's just a definition of everything there yeah okay now if I look at the MVC controller the MVC controllers job is to go out and get those customers and return them as a model as you can see in line 26 to the V you call customers or go get a single customer in line 31 and returning it as a model in line 32 but we need that customer repository so how do we get the customer repository to the MVC controller you inject it yeah as simple as that now of course using what's missing here the registration is missing right obviously I got to build the container no different than that program C S filed bill to the container so in the global a si X is where I'm building my control while I'm doing here is that I'm Red Hood registering my controller exactly now the beauty about this and what makes it really nice is that tendency resolver I'm gonna describe that you see in in this program in the program CS file that you saw here I kicked off the initial resolve problem process by asking the container to give me something okay in the case of MBC we have the control inverted even further for us because we never go and create controllers MBC for the MVC framework creates the controller based on the route yeah and when it creates a controller it does so using a controller Factory but it also does so through a dependency resolver we we have the luxury auto fact gives you a product called the auto FAQ let me open this up the auto fact integration MBC integration prom product it's available from new gate also we also have one for web api there's one for WCF as well and one for a couple of other things and when we have that we hook it up in the global a si X like this that's the answer to your question what is Auto fact dependency resolver the default resolver that without touching this there is a resolver built-in to MBC and its job is to new up the class once and determines what controller needs to use what the name of that controller is its job is to new it up and give it to you all of that is behind the scenes all we've done with this architect with the architecture that NBC put in place is override how that is being resolved by telling it don't just new it up go ask the container for it and as long as we put the registration possibly it's going to ask the container to get the controller for us which is why you're seeing line 25 to 27 register all Mike into all my controllers and once we have given the job of creating a controller to a container we can inject anything we need into it and that's how you do the pendant in NBC and this is exactly how you would do it in web api right so Auto FAC and and these others work they all do missing everywhere yeah so winforms WPF web form a little different a little different a little different because in the web well in web in web in web applications using MVC the kickoff point of code is the controller right and something is already controlling that for something's already given us a controller so by us overriding what gives us the controller on line 31 there and saying get it from artifact we don't have to do anything else but all the but I can all of them you have solely can't but the resolving is going to be a little different because the kick off process for a view or a view model and WPF for example is more manual and then there is no factory that gives you a view automatically like we have a factory that gives us a controller so there may be some manual stuff that you have to do but the concepts are all there and then I think some of the mvvm frameworks have that built in like MDM cross if you're using that it already has dependency injection as part of the framework is that true that I don't know I've never used those I've always done my own my I've always built my own and BPM frameworks but it wouldn't surprise me okay okay so this is awesome yeah it's cool stuff and I wish I wish that I would see this more mainstream and I know I know it's been years and years and years that this has been available to us and that makes it even more frustrating for me well you know I think and one of the reasons we do this show in the first place is that people have heard about it and then they see you know code where there's nothing but interfaces and it's never clear where you instantiate anything and now I'm confused and if I'm confused forget them just they never bother to learn it yeah they never want to learn it the way you just explained it makes it very very easy to understand it's not dart doing it isn't that hard it's not super difficult once you understand what's going on and once you see the value of it it just becomes so easier to write apps into extend apps and expand them and modify them so but yeah so that's it man cool thanks so much for that no problem all right I hope that demystifies dependency and affection I know I'm gonna start using it all the time I do and we'll see you next time on visual studio toolbox [Music]
Info
Channel: Microsoft Visual Studio
Views: 124,252
Rating: undefined out of 5
Keywords:
Id: QtDTfn8YxXg
Channel Id: undefined
Length: 45min 16sec (2716 seconds)
Published: Mon Nov 13 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.