We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

End-to-End Dependency Injection & Writing Testable Software

00:00

Formal Metadata

Title
End-to-End Dependency Injection & Writing Testable Software
Title of Series
Number of Parts
133
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Dependency Injection is one of those terms that advanced programmers throw out with an expectation and assumption of full understanding on the part of the receiver. However, I constantly get asked by attendees, students, and clients to please recommend a good DI product and show them how to use it; and when I proceed to start talking about the subject, it becomes immediately apparent that many don't even know what they're asking about. It's easy to get infatuated by a cool buzz phrase, specially when you hear so many others using it. But to truly understand something you need to start by understanding the problem spaces that it is trying to solve. It’s important to learn the concepts behind DI so you can write software that can be properly tested. So let's bring you totally up to speed then. In this session, I'll explain dependency injection from concept to implementation, and use raw code samples to show you how it works and what problems it solves. I’ll demonstrate how writing abstracted code can help you test your applications much better, whether or not use a DI container. Then I'll get into what a DI container is and some of the characteristics and features it offers. I’ll finish by showing you implementation examples in three different platforms.
36
61
Thumbnail
1:11:04
73
107
SoftwareInjektivitätSoftware developerWave packetRow (database)InjektivitätCartesian coordinate systemProjective planeCoefficient of determinationComputer animationLecture/Conference
SoftwareInjektivitätSoftware developerMereologySoftware developerWordExpert systemRevision controlInjektivitätMultiplication signFlow separationInversion (music)Right angleDifferent (Kate Ryan album)PlanningComputer animationLecture/Conference
SoftwareInjektivitätSoftware developerSocial classSoftware testingWeightApplication service providerDynamic random-access memoryConvex hullDampingInclusion mapDifferent (Kate Ryan album)Process (computing)Sheaf (mathematics)Web 2.0Form (programming)Software testingSoftwareBasis <Mathematik>Computer animationLecture/Conference
Social classSoftware testingApplication service providerWeightSoftware developerDigital rights managementConvex hullSoftwareBasis <Mathematik>State of matterSoftware developerInjektivitätSoftware testabilityOrder (biology)Point (geometry)Statement (computer science)Level (video gaming)MathematicsSound effectCodeSampling (statistics)GodAxiom of choiceCartesian coordinate systemRight angleInternet forumAreaMultiplication signType theoryComputer animationLecture/Conference
WeightApplication service providerSoftware testingSocial classSoftware developerConvex hullVideo gameFunction (mathematics)Limit (category theory)ImplementationInjektivitätType theoryWeb 2.0Cartesian coordinate systemRight angleGoodness of fitReal numberNoise (electronics)Statement (computer science)2 (number)Social classSoftwareMereologyMechanism designLimit (category theory)Functional (mathematics)Multiplication signImplementationComputer animationLecture/Conference
Software developerFunction (mathematics)ImplementationLimit (category theory)Social classMUDConvex hullSocial classMultiplication signLimit (category theory)ImplementationDatabaseUnit testingSoftware testingINTEGRALSoftwareObject (grammar)State of matterComputer animation
State of matterComputer programLevel (video gaming)Statement (computer science)Object (grammar)Social classSoftwareInterface (computing)BitComputer animationLecture/Conference
Software developerAbstractionSoftware testingExecution unitRevision controlSoftwareInterface (computing)Object (grammar)Constructor (object-oriented programming)Convex hullInterface (computing)Social classCodeComputer programAbstractionInstance (computer science)SineProduct (business)ImplementationSoftware testingSoftware frameworkFood energyComputer animationLecture/Conference
Object (grammar)Constructor (object-oriented programming)Revision controlSoftware developerAbstractionSoftwareInterface (computing)Software testingExecution unitConvex hullSoftware frameworkPhysical systemEqualiser (mathematics)Server (computing)Social classInterface (computing)Software testingImplementationRevision controlDatabaseProduct (business)Process (computing)EmailOrder (biology)PlastikkarteInformationVideo game consolePurchasingPower (physics)Point (geometry)Computer fileComputer animationLecture/Conference
Software developerString (computer science)InformationExecution unitHydraulic jumpDatabaseComputer fileEmailPhysical systemImplementationSocial classUnit testingOnline helpSound effectProduct (business)Multiplication signExecution unitSoftware testingComputer animationSource code
Software developerSocial classInterface (computing)Process (computing)Unit testingInstance (computer science)Product (business)Execution unitClient (computing)DatabasePlastikkarteComputer animationSource code
Software developerExecution unitMenu (computing)EmailPlastikkarteInterface (computing)Software testingImplementationExecution unitRevision controlProduct (business)Software frameworkComputer programGoodness of fitMachine codeVisualization (computer graphics)Computer animationSource codeLecture/Conference
Software developerLipschitz-StetigkeitHydraulic jumpTrigonometryVisualization (computer graphics)Message passingRouter (computing)Interface (computing)Object (grammar)Social classInstance (computer science)Software frameworkImplementationSoftware testingRevision controlMultiplication signFormal languageRun time (program lifecycle phase)Computer animationLecture/Conference
Software developerTrigonometryDifferent (Kate Ryan album)String (computer science)Order (biology)Object (grammar)Latent heatRight angleType theoryImplementationTerm (mathematics)Unit testingSoftwareSoftware frameworkProcess (computing)Set (mathematics)Exception handlingSoftware testingExecution unitINTEGRALEmailPlastikkarteCuboidComplete metric spaceDatabaseComputer animation
Software developerAirfoilDigital rights managementException handlingEmailExecution unitPlastikkarteSoftware testingSocial classGraph coloringImplementationProduct (business)InjektivitätComputer animation
Software developerDigital rights managementData structure1 (number)Formal languagePoint (geometry)Goodness of fitWeightLevel (video gaming)Rule of inferenceObject (grammar)Social classInjektivitätComputer animation
Software developerCodeUsabilityInjektivitätPattern languageComponent-based software engineeringRule of inferenceSocial classForcing (mathematics)InjektivitätVideo gamePattern languageSlide ruleReal numberComputer architectureMathematicsLevel (video gaming)Object (grammar)CodeComputer animationLecture/Conference
CodeInjektivitätSoftware developerPattern languageSocial classComponent-based software engineeringUsabilityInterface (computing)AbstractionCore dumpFunction (mathematics)Limit (category theory)Data typeDeclarative programmingConfiguration spaceSoftware frameworkWeightSpring (hydrology)Level (video gaming)ChainObject (grammar)Term (mathematics)Product (business)Inversion (music)Game controllerOnline helpPattern languageInjektivitätForm (programming)Image registrationResolvent formalismPhase transitionCartesian coordinate system1 (number)Social classWeb applicationWeb 2.0Mobile appTouchscreenAssociative propertyComputer animation
Execution unitConfiguration spaceSoftware developerInterface (computing)Software frameworkData typeDeclarative programmingSpring (hydrology)Data structureIntelProcedural programmingExt functorMobile appTouchscreenKey (cryptography)Image registrationElectronic mailing listBuildingForm (programming)Interface (computing)Social classGoodness of fitRight angleVideo gameRow (database)WordAssociative propertyComputer animation
Declarative programmingInterface (computing)Software frameworkSoftware developerData typeConfiguration spaceData structureSpring (hydrology)Procedural programmingInterface (computing)Key (cryptography)WordElectronic mailing listSocial classImage registrationProjective planeMultiplicationProcess (computing)BuildingCoprocessorAssociative propertyStatement (computer science)Revision controlArmCodeConfiguration spaceMathematicsType theoryAttribute grammarComputer animationLecture/Conference
Spring (hydrology)Software developerDeclarative programmingData typeRaw image formatSoftware frameworkInterface (computing)Data structureProcedural programmingConfiguration spaceVariable (mathematics)Constructor (object-oriented programming)Category of beingAttribute grammarSocial classInterface (computing)Type theoryMultiplicationProcedural programmingResultantProcess (computing)Resolvent formalismCategory of beingCoprocessorImage registrationElectronic mailing listParameter (computer programming)Figurate numberAssociative propertyBuildingConstructor (object-oriented programming)Computer animation
Interface (computing)Variable (mathematics)Constructor (object-oriented programming)Category of beingSoftware developer1 (number)Raw image formatData structureWeightSpring (hydrology)Router (computing)Constructor (object-oriented programming)ChainParameter (computer programming)Interface (computing)Social classIntercept theoremType theoryResolvent formalismReflection (mathematics)Computer animationLecture/Conference
Software developerVariable (mathematics)Interface (computing)Constructor (object-oriented programming)Category of beingRouter (computing)CoprocessorProcess (computing)Social classBuildingElectronic mailing listConstructor (object-oriented programming)Greatest elementChainWordRecursionInstance (computer science)Right angleComputer animationLecture/Conference
Software developerInterface (computing)Variable (mathematics)Category of beingStrutDigital rights managementSocial classChainRight angleSoftware repositoryElectronic data processingDatabaseProcess (computing)CodeBuildingCoprocessorPhase transitionRepository (publishing)Reflection (mathematics)Computer animation
Software developerDigital rights managementSoftware repositoryConstructor (object-oriented programming)Repository (publishing)Social classCoprocessorProcess (computing)Projective planeDecision theoryComputer animationLecture/Conference
Software developerJava appletDigital rights managementSoftware repositoryProcess (computing)Social classWeightComputer programInterface (computing)SoftwarePoint (geometry)AbstractionGoodness of fitCheat <Computerspiel>CoprocessorComputer animationLecture/Conference
Software developerAirfoilExecution unitConstructor (object-oriented programming)String (computer science)Software repositoryCoprocessorCodeCartesian coordinate systemComputer programLine (geometry)Graph (mathematics)Level (video gaming)Object (grammar)Social classChainOnline helpComputer animationLecture/Conference
Software developerDigital rights managementExecution unitSocial classOnline helpConstructor (object-oriented programming)Statement (computer science)CodeMultiplication signLine (geometry)Cartesian coordinate systemReflection (mathematics)Different (Kate Ryan album)Computer animationLecture/Conference
Software developerVariable (mathematics)Interface (computing)1 (number)Raw image formatData structureSpring (hydrology)WeightProjective planeComputer clusterClient (computing)Software developerComputer programTriangleState of matterGoodness of fitSharewareReflection (mathematics)Computer animationLecture/Conference
Software developerEmailAdditionInjektivitätLevel (video gaming)Data structure1 (number)Projective planeMathematicsSharewareCodeFlow separationSocial classRegular graphProduct (business)NumberOrder (biology)PlastikkarteComputer animationLecture/Conference
Product (business)Software developerNo free lunch in search and optimizationInclusion mapEmailSocial classOrder (biology)PlastikkarteNumberWordDifferent (Kate Ryan album)System callImage registrationAssociative propertyInterface (computing)Exception handlingFluid staticsSoftware repositoryBuildingCoprocessorProcess (computing)Category of beingComputer animationLecture/Conference
Software developerBuildingSocial classInterface (computing)BuildingCoprocessorRepository (publishing)Image registrationCategory of beingCartesian coordinate systemIndependence (probability theory)Parameter (computer programming)Constructor (object-oriented programming)InjektivitätObject (grammar)Resolvent formalismProcess (computing)Entire functionResultantChainComputer animationLecture/Conference
Software developerSocial classEntire functionResolvent formalismProcess (computing)Chain1 (number)InjektivitätContext awarenessCodeMultiplication signTrailComputer animationLecture/Conference
Convex hullSoftware developerFingerprintConstructor (object-oriented programming)Social classProcess (computing)ResultantReflection (mathematics)ChainResolvent formalismRight angleSoftware repositoryMultiplication signComputer clusterInstance (computer science)Computer animationLecture/Conference
Software developerMUDTwin primeRight angleLine (geometry)Order (biology)Repository (publishing)Social classProcess (computing)Computer animationSource code
Software developerString (computer science)Menu (computing)Software repositoryInterface (computing)Social classOrder (biology)Flow separationSystem callRepository (publishing)CoprocessorTorusComputer animation
Software developerCoprocessorSoftware repositoryUnit testingLattice (order)Compilation albumCodeOrder (biology)Process (computing)Special unitary groupSocial classComputer animation
Software developerInformationFingerprintConstructor (object-oriented programming)Resolvent formalismMultiplication signSocial classKey (cryptography)Interface (computing)Plug-in (computing)String (computer science)Computer animationLecture/Conference
Software developerFingerprintSocial classInterface (computing)Plug-in (computing)Graph coloringConstructor (object-oriented programming)Parameter (computer programming)Type theoryData structureImplementationComputer animationLecture/Conference
Software developerUniform resource locatorService (economics)Instance (computer science)AbstractionFactory (trading post)Repository (publishing)Parameter (computer programming)Cellular automatonCodeWordPattern languageMultiplication signTerm (mathematics)Social classLevel (video gaming)Order (biology)InjektivitätProcess (computing)Right angleComputer animation
Service (economics)AbstractionUniform resource locatorFactory (trading post)Software developerInstance (computer science)Repository (publishing)DivisorSocial classCartesian coordinate systemCASE <Informatik>InjektivitätServer (computing)Computer animationLecture/Conference
Service (economics)Repository (publishing)Software developerUniform resource locatorInstance (computer science)AbstractionFactory (trading post)InjektivitätService (economics)Software repositoryOperator (mathematics)Different (Kate Ryan album)Projective planeClient (computing)System callObject (grammar)SpeicherbereinigungReflection (mathematics)Memory managementCompactly generated spacePoint (geometry)Instance (computer science)Electric generatorComputer animationLecture/Conference
Service (economics)Repository (publishing)Uniform resource locatorAbstractionSoftware developerInstance (computer science)Factory (trading post)Social classCoprocessorInterface (computing)Generic programmingConstraint (mathematics)Augmented realityInformationStack (abstract data type)Object (grammar)Pointer (computer programming)Instance (computer science)Service (economics)Uniform resource locatorPattern languageFactory (trading post)Multiplication signAbstractionTerm (mathematics)CodeClosed setCoprocessorProcess (computing)Social classBuildingInterface (computing)Computer animationLecture/Conference
Software developerFingerprintEmailExecution unitVideo gameUniform resource locatorSocial classRight angleCoprocessorComputer clusterInterface (computing)Computer animationLecture/Conference
Software developerInformationDuality (mathematics)Link (knot theory)Augmented realityFingerprintVideo gameCoprocessorExecution unitDynamic random-access memoryAirfoilService (economics)BuildingCartesian coordinate systemWave packetNumberFactory (trading post)Pattern language40 (number)Point (geometry)Social classWebsiteSoftware repositoryComputer animationLecture/Conference
Software developerFingerprintInformationMenu (computing)VacuumGraph (mathematics)Factory (trading post)Software repositoryUnit testingPattern languageOperator (mathematics)CodeControl flowComputer animationLecture/Conference
Software developerElectronic mailing listQuarkFingerprintInformationColor managementGraph (mathematics)EmailService (economics)Pattern languageCoprocessorUniform resource locatorBuildingUnit testingInsertion lossRight angleProcess (computing)Instance (computer science)Social classWordObject (grammar)Semiconductor memoryLeakMathematicsAssociative propertyImage registrationImplementationWeb applicationParameter (computer programming)Arm2 (number)Wave packetChainDifferent (Kate Ryan album)1 (number)Computer animationLecture/ConferenceJSON
WebsiteInjektivitätProxy serverComponent-based software engineeringControl flowSurjective functionRadical (chemistry)Software developerProgrammable read-only memoryWeb applicationSemiconductor memoryLeakProxy serverGame controllerProcess (computing)InjektivitätService (economics)Design by contractIdentity managementPerfect groupCAN busInterface (computing)Social classWeb 2.0Parameter (computer programming)Constructor (object-oriented programming)Type theoryState of matterComputer animationLecture/Conference
InjektivitätProxy serverComponent-based software engineeringControl flowSurjective functionWebsiteRadical (chemistry)Programmable read-only memorySoftware developerConvex hullGame controllerWeb 2.0Proxy serverSemiconductor memoryLeakDifferent (Kate Ryan album)Instance (computer science)Computer animation
Software developerPort scannerConvex hullDigital rights managementSharewareCoprocessorRight angleWebsiteAuthorizationPay televisionHookingComputer animation
Software developerConvex hullHookingPay televisionSocial classSoftware testingSingle-precision floating-point formatObject-oriented programmingPlastikkarteRight angleElectronic visual displayMultiplication signComputer animationSource code
Information Technology Infrastructure LibrarySoftware developerACIDFermat's Last TheoremAirfoilConvex hullExecution unitMultiplication signSystem callOrder (biology)Right angleSoftware testingSemiconductor memory1 (number)Process (computing)Single-precision floating-point formatInstance (computer science)SineBitComputer animation
Category of beingSoftware testingInstance (computer science)Single-precision floating-point formatSocial classVariable (mathematics)Pattern languageCartesian coordinate systemSource codeComputer animation
Functional (mathematics)Instance (computer science)CoprocessorCartesian coordinate systemUniform resource locatorRevision controlProcess (computing)Multiplication signVariable (mathematics)Computer animation
Variable (mathematics)System callSocial classResultantComputer animation
Social classVideo gameCASE <Informatik>Computer programAbstractionInterface (computing)Arithmetic meanRight angleSound effectUniform resource locatorMultiplication signComputerResultantComputer animation
CoprocessorUniform resource locatorHecke operatorSocial classResolvent formalismRight angleWordMultiplication signComputer animationLecture/Conference
Computer programResolvent formalismFluid staticsChannel capacitySocial classInterface (computing)System callResultantPlanningComplete metric spaceImage registrationComputer animation
SharewarePort scannerImage registrationSoftware developerSocial classSet (mathematics)Type theoryInterface (computing)1 (number)CoprocessorExpressionLambda calculusCASE <Informatik>Process (computing)Projective planeComputer animation
Software repositoryModule (mathematics)Function (mathematics)Image registrationCoprocessorSocial classSharewarePosition operatorType theoryCASE <Informatik>Interface (computing)Different (Kate Ryan album)Process (computing)CodeNP-hardComputer animation
Type theoryInterface (computing)Client (computing)Module (mathematics)Assembly languageProcess (computing)Configuration spaceInformationSoftware repositoryRight angleProduct (business)Proxy serverImage registrationCoprocessorRepository (publishing)Computer animation
Image registrationSocial classPlug-in (computing)Number3 (number)BuildingWordInjektivitätInterface (computing)Order (biology)ComputerString (computer science)Constructor (object-oriented programming)Computer architectureIdentifiabilityParameter (computer programming)IntegerFlow separationModul <Datentyp>CASE <Informatik>Default (computer science)Product (business)1 (number)MathematicsCausalityComputer animation
Software developerProgrammable read-only memoryMultiplication signDefault (computer science)Parameter (computer programming)CASE <Informatik>Number1 (number)Constructor (object-oriented programming)System callProcess (computing)CodeInjektivitätOrder (biology)Point (geometry)MathematicsCoprocessorUniform resource locatorDeterminismComputer animation
Port scannerSoftware developerInformationLoginQuarkCantor setEmailVacuumDrag (physics)AirfoilFluxPoint (geometry)CoprocessorUniform resource locatorConstructor (object-oriented programming)Parameter (computer programming)MathematicsBitCodeOnline helpGodAttribute grammarComputer animationLecture/Conference
Software developerExecution unitAttribute grammarExecutive information systemConstructor (object-oriented programming)Attribute grammarCASE <Informatik>Type theoryComputer animation
Software developerPort scannerQuarkMenu (computing)VacuumConstructor (object-oriented programming)Image registrationCodePlug-in (computing)Control flowSharewareMultiplication signProjective planeOnline helpTwitterSheaf (mathematics)EmailComputer animationSource code
Execution unitSoftware developerDrag (physics)Cantor setConstructor (object-oriented programming)Feasibility studyDeterminismInjektivitätInterface (computing)Extension (kinesiology)Product (business)View (database)AbstractionContent (media)Social classWeightApplication service providerGrand Unified TheoryFactory (trading post)Game controllerDisintegrationMultiplication signCodeInjektivitätProduct (business)Group actionCartesian coordinate systemForm (programming)Game controllerSharewareWeb 2.0View (database)WebsiteLink (knot theory)Electronic mailing listSlide ruleSpeech synthesisComputer animation
Software developerWeightApplication service providerPerturbation theory1 (number)InformationComputer animation
Transcript: English(auto-generated)
I don't do Q&A at the end of a talk. If you have a question, just raise your hand, ask me in the middle of it. I don't want you to lose your train of thought in asking a question, so I don't make you wait till the end. I'll be repeating the question so we can have it on the record since this whole thing is being filmed and recorded.
And welcome to DI. So I wanna ask a question because I'm gonna anticipate what you guys may not ask, but I usually get this asked by a lot of other speakers. People will approach me and say, why are you still talking about DI? Everybody's doing that. And I don't know about Europe because it's a very, very different audience,
but how many people here use dependency injection mainstream in all their applications at work in the projects they're working on? You see? A handful of you, probably less than a quarter of you. In America, an audience of this size, I get two or three people that raise their hands. And it's really a sad thing
because that's the whole reason why I still talk about this subject. This is one of those things that needs to become mainstream. It's a very important part of software development today, and it's not rocket science. It's not difficult to do, and the benefits are huge. There was a time several years ago where dependency injection, inversion control,
containers, all those kind of, that kind of lingo was what the cool kids were doing, right? It was the buzzwords. And everybody wanted to do it because it just sounded really cool, and I know that's what the experts were working with. It's not like that anymore, and it shouldn't be like that. It shouldn't have been like that back then. This is something that's important and that should be part of all of our software development.
What's going on with that thing? Am I supposed to avoid that section? I don't know. All right, so what we're gonna talk about is the difference between coupling and non-coupling. Now, some of the stuff that I am gonna go over,
you may already be familiar with, but I do things in a step-by-step process because I'm gonna build up to the actual usage of DI. This talk is supposed to be a 75-minute talk, but in NDC, they only do 60 minutes. So you're gonna find me rushing through a couple of things.
I'm gonna try not to rush. What I'm gonna do instead is there's a section at the end here. What is going on with this thing? What was that? Did you say post-back? This frickin' thing was written in web form? Is that what you're saying? So I go through the explanation
of dependencies and what coupling is and how with coupling, you don't have testing, and I'm gonna go through that and get into decoupling and why testable software is very important and what is the basis for testable software. Then I'm gonna get into dependency injection because the truth of the matter is that
in order to use dependency injection, you have to set the groundwork for it, and the groundwork comes in making your software testable. If you can just get to that point and abstract just enough to make your software testable, you've accomplished more than your average developer, at least in the States, which is a really sad statement for me to make, but that's the God honest truth.
Then from there on, DI can help you take it to the next level. Now, I'm gonna go through all of this because I'm gonna go through, I use AutoFac, by the way, in my examples, but I do have code samples for you to take with you that are in all the other containers, probably like four or five other containers, including MEF, but AutoFac is my container of choice. The area here is what I may or may not get to,
depending on how we do with time, but what this is, they're four complete working examples of dependency injection usage in all these four types of applications, including a web form's applications for this post-bac guy right here. So you got some real good real-world usage scenarios
there that I will try to get to, but I'm not gonna guarantee it because of the fact that I only have one hour. So all of this starts, this thing is flickering, by the way. Every once in a while it just kind of flickers. Well, let's see if it, it's not gonna do it. It's like bringing your car to the mechanic. It doesn't reproduce the noise,
so it's not gonna reproduce it now. So the idea of writing testable software involves breaking this lifelong habit, and the lifelong habit involves class coupling. I'm gonna get into that. I'm gonna go back to that statement in just a second. Coupling very simply, as I'm sure a lot of you know, it's just one class depending on another. The class cannot exist, cannot function.
Most of the time it can't compile without some kind of partnership class, some kind of partner class. This has a lot of limitations. The first one is that it limits you to single implementations because you got one concrete class depending on another. So for example, you got one class that performs database work in your data access layer. You got a business engine class that calls upon that.
Those things are very tightly coupled. If they're very tightly coupled, it becomes difficult to test. The reason it becomes difficult to test is because you can't write a unit test against that business engine class without it hitting your database, which is not something that you want to do in a conventional unit test. That's something that you reserve for what we call integration tests.
So this kind of coupling where we have concrete classes depending on one another is generally bad. Now, why is it bad? Well, the answer to that question is in the secret to writing testable software, which is that breaking a lifelong habit that I told you about, and that is stop newing up objects inside a class. Now, my general experience with European audiences
is that they're a little more advanced than a lot of audiences that I speak to in the States. I don't know what the reason for that is. I don't think it's because your skill level is higher than American programmers. I think it's because American conferences attract primarily newbies. At least that's been my experience.
So when I make a statement like this in front of a hundred people that just got into programming two or three years ago, it's usually a shock and awe statement. What do you mean stop newing objects in class? How else do you expect me to instantiate an object? Well, there are other ways of doing it. The first step to writing testable software
is to embrace abstractions, and you do that by using interfaces quite a bit. And this gets, I get fight back on this statement quite a lot, because people tell me, well, that's why I don't like to code that way, because I end up with almost an interface for every class.
Yeah, you kinda do. That's not a bad thing. There's nothing wrong. We're programmers, we like to program, we like to write code. Why are we trying to get out of the idea of writing code if it's the right code to write? Having an interface for most, if not all of your classes, lets you pass these interfaces around. This limits the coupling massively,
because now one class does not depend on a concrete instance of another one, it depends on an abstraction, a definition of it. And now that definition can vary depending on the scenario. So in the production world, the definition of a class that gets used by another
is one implementation in a testable scenario. In a test world, it may be a different implementation. Let's go back to that example about the data access layer class. You have a concrete implementation to production that uses entity framework and system.data, ADO.net, all that fun stuff, to actually access SQL Server.
But in the testing scenario, you can use a test version of an interface, so it's a different class. It's got the same create, read, update, delete, same methods that normally go to the database, but they do something else that don't physically hit a database. And now by passing that implementation into another class,
you've just made that class extremely testable. This is gonna make a lot more sense when I show you code. Actually, I'm gonna show you code right now. How about that? Unless you guys rather stay in PowerPoint, what do you prefer? All right, where is,
so this is a very simple coupled example. I'm just gonna go through a really, it's stupidly simple because all I have here is I have a commerce class that's got a method called process order. And the commerce class has broken out the idea of processing a customer's order into four different steps. One of them is to update the customer database.
The other one is to run the customer's credit card. Another step is to log the information to like a audit log or something. And the other one is a notifier step which sends out an email to the customer saying, thanks for your order, here's your receipt, right? Now, I got these steps broken out into four different classes. Now, all the steps we're doing
is writing out to the console. So obviously, you're not doing anything crucial. But this is where you would process a customer's credit card. This is where you would write out product and customer purchase information to an actual database. This is where you would use, let's say, log for net or something to write out to an audit log
that may go to either a text file or a database. And this one is gonna access system.mail to actually send out an email. So all of these have pretty concrete implementations of what they're supposed to do and the kind of implementations that you don't wanna run over and over again if you were testing this class. Now, if we're running all four of those steps
from this commerce class here, the commerce class is gonna rely on those four helper classes. And as you can see, they're completely tightly and very poorly coupled to the commerce class because they're being instantiated right here. If I'm gonna instantiate this class in a unit test scenario, I'm gonna have the exact same effect as if I'm running it in production.
And that's not what I want. I don't want to access the database from here. I don't wanna send out an email every time that a unit test is run. So this is a perfect example of just some really poor coupling. So how does this get fixed? Very, very easy, actually. If all of these classes have a corresponding interface
that defines them, in this case, iBuildingProcessor defines this one. As you can see, it's just a quick definition. The other four, which I won't bother showing you, are exactly the same. They just have a corresponding interface. Now that's what's being used here.
Now, as you can see, I can instantiate the commerce class and send in instances of these classes during production. But the beauty of this technique now and why it's considered testable is because now from a unit test, I can decide what I want to send into here.
I can decide what I want to send into here that does not actually perform those concrete steps. It does not send out a physical email or notify the client, does not update the database, and certainly does not process a credit card. Can you imagine that concrete step being run over and over again in a unit test? That's not what we want.
In a testing scenario, we would like to set up test versions or test implementations of each of these interfaces. Now, that becomes a whole lot of work, and that's usually one of the reasons why I get pushback from people. Well, if I have an interface, now I gotta have a production implementation, I gotta have test implementation.
First of all, yes, you do. That's just good coding. It's good programming to have two different implementations, one for production, one for test. But there's an easy way to get the test done that I'm sure at least some of you in this room have done something with. Has anybody worked with the Mocking Framework before? All right, quite. You see, more people than have worked with the DI container. How about that?
That's weird, to be honest with you. So this is an example of using a Mocking Framework. I don't know what Visual Studio, Visual Studio does those retarded things once in a while. It just stops. You ever get the general message from Visual Studio saying I'm busy? Visual Studio is busy.
Is that rude or what? I got shit to do. Don't tell me you're busy. All right, so this is an example of using Mach-Q, okay? Now I'm not gonna go through a tutorial on Mach-Q, but just to show you what I've done here is that ultimately I need to instantiate my commerce, but obviously my commerce class needs four instances of each one of those objects,
those implementations of those four interfaces. What a Mocking Framework allows you to do, for those of you that have never seen it before, is create a test version of an interface, a test implementation of an interface, but do it all at runtime. And depending on how the Mocking Framework is written, the language is just going to vary a little. Here all I'm doing is that I'm creating an object
that's a mock of iCustomer. Then I am taking mockCustomer and setting it up. And what you can do in the setup here is a ton of different things. I'm keeping it very simple. I'm saying whenever you call updateCustomerOrder with any string and with any string, don't do anything else. But if customerOrder happened to return something, I can then do a returns here
and return whatever the object is that it needs to return. If I wanted to set up this mockCustomer so the updateCustomer works only if this string is something specific and this string is something specific, I can set it up that way. Once I have my whole mock set up, I can just address it as mockCustomer.object.
And this type right here is actually an implementation of iCustomer. So a mocking framework should definitely be in your toolbox as you start writing testable software, as you start writing software that is geared for testability. Very important. And now I can run this unit test
and remember the idea of the unit test is to test that process order, complete it without exception. It's not the test that process order updated the database, sent out an email and processed a credit card. That's an integration test. I just wanna make sure that that unit complete it without exception and I can do that by sending these mocks into there.
So very, very simple process. Now, if I go out to here, you notice that this class cannot work, cannot instantiate without four implementations of these dependencies, these dependent classes. So something has to instantiate these classes
and send them in. Obviously, whatever the caller is, okay? Now, this is where the use of a product helps us a lot and that product is known as a dependency injection container. I'm not here to push any product. I happen to like AutoFact because it's what I use and it's easy for me to use
but use whichever one you're familiar with. Anybody use Castle Windsor here? Okay, three people. Structure Map, two, three. Ninjak, couple more. Unity, I'm sorry. What about AutoFact?
Okay, they're all good. The language for them is just a little different, that's all. AutoFact happens to be the, I think it's the newer one. So it was written in .NET 4 or 3.5 or 4 so it's one of the newer but they all do, these guys that wrote these containers are very competitive with each other so if one guy adds something to Castle Windsor,
then Jeremy who wrote Structure Map immediately goes and puts out an update for Structure Map to compete with what Castle Windsor just received. So they're all gonna do very, very similar things. It's a dependency injection container that is going to not only take care
of injecting these dependencies into this class but it's also going to eliminate that rule that I told you earlier that I said was usually a shock and awe rule of not newing objects up because something has to new it up, right? If this class is not gonna new up these classes which we don't want it to, then whatever calls commerce
is gonna be newing up these classes and sending them in but we're gonna eliminate that as well and we're gonna do it in a very cool way because I'm gonna show you how recursively we can go as low as we need with one class calling another, calling another, calling another and let the dependency injection container take care of everything for us. Let's go back to the slides real quick.
So dependency injection in general is just a pattern. It's an architectural pattern. It's designed to satisfy the dependencies in a class. You just saw an example of one class with four dependencies. It helps us resolve the dependencies
when we wrote our code in a very decoupled way without having to worry about instantiating those dependencies from any level in our object chain. We eliminated the instantiation from that commerce object but like I said, something has to instantiate it or we're gonna actually eliminate that as well. You're gonna see how cool it's actually gonna be.
So this pattern gets a lot of help with the help of this product, this product known as a container. Another term for dependency injection container is an inversion of control container. The terms are kind of used interchangeably. Put simply in its basic form,
a DI container, as I'll call it going forward, is all about two things, registration and resolve. A DI container will have a registration phase at the beginning of an application done once only. If it's a web app, it's done in the global ASX
or a class that's called by global ASX. If it's a WPF or WinForms or some kind of desktop app, it's done at the beginning of app load, probably while the splash screen is loading but it only needs to be done once. And the container itself is held onto class-wide, statically typically.
And all registration is, is the association, the building of a list of key value pairs associating a class to an interface. In its simplest form, and I say simplest form because there's a couple of things that I'm gonna throw in there that are going to complicate it a little more,
but that's good. I suspect you guys are not newbies, so a little complication in your life, especially when it comes from an American, is a good thing, right? That was supposed to be funny. Laugh a little, we're on the record, it's being recorded. Laugh into the microphone. All right, so it's about building a bucket
of key value pairs. I hesitate to use the word bucket list because it's very morbid. But it's a bucket of key value pairs associating one class to an interface. This is what's called, this is registration. So in the examples that I showed you, the building processor class is associated with the iBuildingProcessor interface,
the logger class with the iLogger interface, and so on. And some of these registrations can get really, really long. I've been known to register two, 300 different classes for a large project. Every container has multiple ways of doing its registration. Most of them now support all of these things. The most common way of doing it is procedural,
which means you're gonna see an actual code statement that registers, register this class to this interface. But there's ways of storing those associations in a config file. There's ways of doing discovery, MEF does it through discovery, where you tag classes with an attribute
and that attribute relates it to the interface. So later, MEF goes out and discovers everything in your types with who's using this attribute and this is how I can tell that this is the interface that you're using. So there's multiple ways of doing it. We're gonna stick with the procedural way in our examples. The second thing that the container is used for
is the resolve process. And that is when the need for a dependency is encountered. And I'll go over the detail on when that is. But when that need is encountered, the container will say, okay, I have a property or an argument or something here that's of type iBillingProcessor.
Let me go into that bucket list that I created, that you created during registration, and figure out what is iBillingProcessor associated to. Ah, it's the billing processor class. Let me knew it up and inject it into that constructor. And that's how the container is gonna take care of us
not having to knew up objects anymore. But this is where it gets really, really cool, because it kicks off a chain reaction, a DI resolve chain reaction. So let's go back to that example again. You saw the commerce class relying on four constructor arguments of four interface types.
When that commerce class is created, and it's gonna be created by the container, the container's gonna resolve it. The container is going to use reflection, and there's reflection involved here, so get over it. If you have a fear of reflection, get over it. Reflection's not as heavy as people think, if used right. The container's gonna take that commerce class,
it's gonna reflect into it, look at the constructor, and see that it's expecting four interface types. Now, before the container can knew up the commerce class, it knows that it needs to, it knows that it needs to instantiate those four classes so that they can inject them in there.
So it's gonna go to each one. So it starts with the billing processor. It goes back into its bucket list and says, okay, iBillingProcessor is associated with billing processor. So before it knews up billing processor, guess what it does? It goes into the billing processor class, looks to see if it's got any dependencies
in its constructor. If it does, it performs the exact same process. When it finally gets to a bottom of the chain where it has no more recursion, no more dependencies to resolve, it then says, okay, now I'm ready to knew this class up, take the instance of that and inject it into this one,
finish the dependencies for this one. Once this is done, knew this one up, inject it into this one, finish the dependencies here, and it keeps doing that back up the chain till it gets to the original host that asked for the commerce class. What this means is that this class right here has only four dependencies.
However, this class has, well, you can see from a previous example, has no dependencies, but I commented out some code here that I did for the previous session that I did at the previous conference where this billing processor had a dependency for a data repository to access the database.
If that class, if that interface, iDataRepository, is registered to an actual data repository class with my container, then when the container goes to resolve this here, when it sees this, it hasn't instantiated this yet,
it's still in the reflection phase. When it sees this, it says, okay, let me go into this one and knew it up. Oh, hey, I can't knew this up yet. It's got a dependency. So let me go into here. What is this registered to? A data repository class. Does this have any constructors? Nope, this one doesn't, no dependencies.
So let me knew up the data repository, put it into there. Now there's no more dependencies. I can now knew up billing processor. Now I have a class that I can inject right into there. This is the container talking. I can inject it into there, onto the next one, and it performs the same process for the next one.
The beauty of this is that once you have all of your classes in your project registered with a container, you can start using class. I made the decision to add the dependency of IDataRepository to billing processor later in my project. Perhaps I had data access stuff in here,
hard coded into here for whatever bad reason because I was a poor programmer, and I just had pure ADO.net in here. I didn't like it, so I refactored it into a data repository class, and then what do I have to do to add that to billing processor? All I gotta do is add it as a constructor there. The container will take care of instantiating it for me.
It's a very, very nice solution. If I didn't have the container, but I went ahead and I did all of this decoupling, I've gone halfway. I've gone a very good way because I've written testable software. By getting just to the point of embracing these abstractions and working with these interfaces,
you're writing testable software. You're doing things much, much better, but you're also doing things a little harder. You're making it harder for yourself because now, yes, I'm able to test these classes because of the abstractions, but now, whatever is instantiating billing processor has to inject that in there manually, and if that something is up here,
well, I don't wanna new it up in here, so now, whatever is installing this has to inject, has to new up billing processor, and in turn, has to new up data repository and have new of this, new of this, new of that, and then new up commerce with this string of constructors and it just becomes a lot more difficult.
You're gonna see how easy it is when I show you the DI code. Everybody got a pretty good idea of what I'm talking about? When you find yourself having to add dependents, it's gonna happen when you do that because I do get fight back from people. What you've explained is cool, but it's still more complex.
I'm adding more to my application. It's like a lot of things in programming. You add a little up front for a lot of benefits down the line. When you set your stuff up good from the beginning, when you find yourself having to add dependencies at any level in your chain, let's say you have a five-level object chain, object graph.
This class uses this one. This one uses this one. This one uses this one. All of a sudden, this one needs a little help from another class that you wrote. Well, as long as you register that class in the container, just add it to the constructor. Everything falls into place. There's nothing, you don't have to keep backtracking. Okay, what got me there? Because I gotta new it up somehow. No, the container will take care of all of that.
And that's why I made the statement stop newing up classes. Now, I think, no, no, no, it's no impact. The only impact, and usually the question that I get is is there an impact on performance?
Well, anytime you add a line of code to your application, there's an impact on performance, obviously. This uses reflection. So if you're one of those people that's a little reflection-phobic, yeah, you're gonna add nanoseconds of hit. Are you going to be able to tell the difference? Probably not. But the most important thing is are the benefits,
is the return on your investment worth it? Like everything, you have to ask that question. You can't go into a programming project thinking it's always gotta be about performance because the performance of you as a developer is equally important. You know how clients are, they want it right now. Do you guys have the famous triangle
that we have in the States? You can have it cheap, you can have it fast, you can have it good. Pick two. Try telling that to a client. Doesn't go over very well. You'll get a chuckle, that's about it. And then you're starving for the next six months.
Besides, reflection is, it's gotta be used wisely, but if it's used wisely, reflection, the return on investment with using reflection properly is huge. Absolutely huge. I'm gonna go through the first demo quickly and then I have additional DI techniques that I wanna show you because that's why this session's called End to End.
So let me see where we are. 606, all right, we're cool. Just to show you what this is set up like, this solution, I'm using this one project here for the rest of the hour, DI.autofact. But I have examples in Castle Windsor, Mef, Ninjex, Structure Map, and Unity.
And I'm gonna show you all of them with just this first demo, this first example, so you can see what I'm doing. My demos are all, I take a lot of pride in the way I write my demos. I don't like to keep changing code on the fly because then you take the code home and you can't remember what was what and what changed to what. So all my demos are completely separate pieces of code
so you know exactly what they are and they're numbered here. So this first one that we're gonna do is called regular DI usage. And just to show you, we have a worker class here, the order info, this is nothing but a data class. This is what's containing all the data that we're sending to the order, okay? This will have a credit card number in here, whatever.
And in AutoFac, we have two classes that we deal with when we create a container. Usually, containers have one class, their container. AutoFac has the container builder and then the container is generated from the builder. It doesn't make it that much different
from any other container. It just makes it where it's two classes instead of one. That's all it is. And you're gonna see the difference in a second with the other containers. So what I'm doing here is that I am creating a class called container builder because it's off that builder class that I'm gonna do my registrations. And this is how I'm registering here. Remember what I told you? It was just an association.
This is in its simplest way possible, association of a class to an interface. Now, you see one exception to that association of a class to an interface and that's up here. I'll talk about that in a couple of minutes. But as you can see, I'm registering building processor to its interface, customer processor to its interface, and so on. Here's iData repository to its interface.
Then I'm building the container out of those registrations. That container is a static property on this program class, so the entire application has access to it. I'm resolving the commerce class. I'm not even newing up the commerce class. You remember, the commerce class has a four argument dependency in its constructor.
So if I'm gonna new up the commerce class, I would have to say commerce obj equals new commerce and in the constructor send in four different objects and I don't wanna do that. The whole beauty of using DI is that I can tell the container, please get me the commerce class.
Now, in a dependency injection container, they all have their technique for resolving. You can ask for either a concrete class or an interface. If you ask for a concrete class, you're gonna get that concrete class with the entire dependency resolve process being done for you down the chain.
If you ask for an interface, you're going to get whatever class that was associated to it registration. Some containers require you to register concrete classes as well. Some don't. Why? I have no idea. I think Unity requires you to register concrete class.
I may be wrong. Castle and Ninject do not. I guess we'll see in a second because I'll show you the code. But you can choose to resolve anything you want but if that anything happens to be a concrete class, AutoFact specifically requires you to register it.
I'm not associating it to anything but I need to make AutoFact aware of this class ahead of time. I really don't know why. Maybe it just likes to keep track of things. Once I do this, that whole resolve process starts. That whole reflection chain that I told you about, how it goes recursively down everything's constructor,
every class's constructor until it's able to resolve everything and come back up, that's what happens with that simple resolve right there. So it's a very, very cool solution to obtaining a fully qualified instance of the Commerce class completely filled
with everything that needs to be filled. There was a time where I didn't have that data repository as a dependent. As a matter of fact, I didn't have it today. If I run this right now, I thought I just ran. Did I just run?
No, I guess I didn't. I have five, here we go. Did I mention that I embarrass people when they leave the room?
Let's talk about him. Anybody know him? What country is he from? Come on, we gotta insult him somehow. All right, check this out. Each one of those console write lines just ran. So all I did was call the process order. It resolved all the classes. Now, I don't know if there's anything
inside the repository but let's find out. Watch this. If I go into that repository, what was that repository? Was it in customer processor? Yep, it was right here. It's down here. Okay, so let's say we do this right here.
And in here, we're going to,
I just ran everything successfully for you but now I decided I'm gonna refactor a lot of crap out of updateCustomerOrder, put it into a separate class called DataRepository because I want it reusable, make this whole situation testable by abstracting DataRepository to an interface
and then simply injecting that interface just like that. And now I can expand on the scope and actually make a call to save right here.
That's all I need to do to have customer processor now depend on a data repository. I don't have to worry about newing it up. I don't have to worry about where's it being called from. It can be called from 15 different places, I don't care. Let's see if that works. They didn't even compile.
Isn't that supposed to be your first unit test? Compilation? Whoa, what happened there? That was not my fault, that was code rush. Sorry, Mark. There we go.
All right, now let's see. One, order processing, payment process, log into it. There you go, right there. We know we hit that class. Without worrying about having to new it up, where's it coming from, who has to new it up, where is this being sent into, it doesn't matter.
As long as I register it, I can now use that in any constructor that I want. The container will take care of the resolve all the time. Pretty cool? That is about as simple as it gets. Yes, please.
So I'm gonna answer that. The question was, I'm gonna get to that. The question is what happens if you have multiple classes implement one interface, how does that work out? And the answer, I'm gonna show you, there's two answers to that. One is some containers allow you to register classes
to the same interface and identify them with a string key. And then somehow you have to get that key at resolve time. I don't like that solution, I think it breaks, it couples, it brings me back to a little too much coupling. The most common scenario I have for multiple classes to the same interface is if I have some kind of plugin situation where I'm going to inject,
I want a collection of this interface to be injected into my class. And that's the example I'm gonna show you later. So I'm gonna have three different classes that implement the same interface, and I'm gonna register all three to the interface, but then what my host class is going to receive
in the constructor is not an argument of this interface type, because the container will get confused if it sees that, even though you can mark one with the primary, being the primary. But I'm gonna inject an IEnumerable of that interface, and the container will actually instantiate all three of them and put them into that collection.
And now my class has access to all the implementations of that. Those are the two primary scenarios, at least that I can think of. Now there's other techniques that we deal with in the world of DI.
And I get a lot of argument from people on this, and I'll explain why, but I'll tell you what. This solution that I'm gonna show you has saved my ass many, many times, and it works. And I don't find anything particularly wrong with it, even though some people consider it an anti-pattern. I hate that term anti-pattern. I think that's as stupid a term as the word code smell.
To me, if you have a code smell, go take a shower and keep coding, okay? So sometimes a class may receive many injections. Sometimes, let's say the commerce class, for example, right now it's depending on four dependencies, right, at the class level. Now that's because my process order method
is using all four of those. But I can just as easily have a more complicated commerce class with, let's say, three different methods. One of the methods uses all four dependencies. One of the methods uses two dependencies. Another one uses just one of them. So depending on what my host application is doing
when it calls commerce, it may call commerce with the intention of calling upon the method that uses one dependency only. So in that situation, I have unnecessarily forced a container to instantiate four different classes just to get the commerce class newed up,
when at the end of the day, I'm only gonna use one of them. So I have three classes that were instantiated unnecessarily. It doesn't sound like this is a big hit, and in the case of four, it's really not a big hit. But I have had classes where I'm depending on seven or eight or nine different dependencies, and I'm only using one or two.
A very typical place, I think, for this scenario for me is I use a lot of WCF, I'm still very heavy in the world of WCF, and I use dependency injection from WCF services, and some of my services have 10 or 12 operations. And a lot of them retrieve data. So I have a lot of different data repositories in my project, and that service may actually depend
on 10 or 12 data repositories. But the operation that the client happens to be calling may only need two of them. So why do I need to instantiate the other 10 data repositories that I'm never gonna use during that call? Object instantiation is not cheap. Make no mistake about that, it's heavier than reflection
because there's a lot of stuff that has to happen with instantiation. I mean, you need to make sure that the heap has room for your object. If the heap doesn't have room for your object, then garbage collection needs to be run, the heap needs to be compacted, generations have to be calculated. There's a whole ton of stuff that has to happen just to get that object out on the heap and the pointer created on the stack.
So if I can avoid instantiating 10 objects and instantiate just the two that I need, I'd prefer that. So this technique is for on-demand instances. It's basically called the service locator pattern. Another term for it is the abstract factory pattern. Very, very similar. Those patterns are not identical, but they are pretty similar.
And I'll show you how I do this. I'm just gonna run straight to the code so I don't run out of time. Let me close this up. And I'm gonna come out here and go to Commerce 2.
Now take a look at Commerce 2. Commerce 2 is not receiving as dependencies the iBillingProcessor, iCustomer, iNotification, iLoggingProcessor. It's receiving this iProcessor locator class. An iProcessor locator class is an interface, so it does get registered in the container to a class.
And the class that it gets registered to is this class right here. This is an AutoFAC processor locator because it's using the AutoFAC container right from here. So I'm just forcing, I'm implementing one method here called getProcessor of T and returning T.
Now I can inject the iProcessor locator into my class and ask it to create the interfaces that I want because it's gonna resolve them from the DI container. Now in this particular method, I'm not gaining anything because I'm doing all four. But if I was calling another method
that's only using one class, let's say the LoggingProcessor, and that's all that I need, then I'm instantiating the other three unnecessarily if I put them all up here. So this is a technique that I use pretty heavily. Has anybody ever watched any of my Polarsight courses? Nobody has, what, one person? And three people.
Thank you, ladies. Thank you, sir. I'm gonna give you guys a big prize that nobody else gets, okay, later on. It's probably a lot of money. Which course have you watched? Okay, so the first, the building multi-client end-to-end service-oriented application, that's the long one, right? The one that's like 55 hours long?
Yeah. Oh, I know it's long. It's, you know, it's training. It's called training. Have you watched my WCF course? So that's another number one course, and that one is, I think it's 11 hours long. But WCF's the topic that I, it takes me five days to teach it. I do a 40-hour on-site class on that.
So these topics are big. Anyway, my point was not to digress to this course. In that course, I do this pattern. This should look familiar to you, because this is what I'm doing with the business engine factory and the data repository factory, the exact same pattern, exactly the same one. So the reason that a lot of people think to say that this is an anti-pattern
is because they say that when you look at the, when your unit test looks at the constructor, all they see is this, and you'll never have any knowledge of what dependencies your operations are gonna use, unless you look at the code for this dependency. You have to decide whether that's a problem for you or not.
I don't have a problem looking at this and just seeing this. I'm gonna go into the code and say, okay, this method is using these four, this method is using these two. I have no problem with that. But it's for that only reason why this pattern, some people document it as an anti-pattern. And the problem is that when somebody puts that into a book,
other people read it and they think it's the Bible and all hell breaks loose and that's why I don't read books. Well, not tech books anyway. Anyway, so this is the service locator pattern and it solves the problem really, really well because now I can just ask for this when I want it. And you can test this with no problem. I can create a mock for this and in that setup,
I can do a mock of the processor locator and set it up so that when the getProcessor is called with iBillingProcessor, return a mock of iBillingProcessor. So I don't lose anything in unit testing. And I do all this from my Pluralsight course.
I'll show you how to write the unit test for it. It's doing it again, isn't it? It's not the podium. Huh? No, I don't think it's me. It's the guy back there. He's messing with me. He's got his hand on a little button. He's going, watch this. You'll see how, ha ha.
Mess with the American. All right, I gotcha. All right. To use this, it's no different. You just saw what the Commerce class looked like. All I did was add the processor locator to the registration. That's it. I didn't change anything here except go resolve this.
I didn't change that. I changed the Commerce class. I changed the dependencies of the Commerce class and what the implementation inside of it was but everything outside of it, nothing has to be changed. I didn't change whatever. If something was calling the Commerce class and it was not the container, that something would have to change because that something went from sending four arguments to sending one argument.
But this has not changed at all. The container takes care of it all. So here's another one, instance lifetime. Instance lifetime is something that has been a problem
and I don't exactly agree with the way these containers were designed to handle this but instance lifetime has to do with two things. One of them is the singleton versus transient which is fine, that's easy. The other one is the disposable stuff which I'll talk about in a second. Containers will let you register the associations,
the classes for conventional transient lifetime or singleton. What that means is that I can register any one of those things so that whenever anything down the chain asks for an instance of iBillingProcessor,
they get a new instance of iBillingProcessor. I could also register it so that it's singleton pattern so that when they ask for iBillingProcessor, the container will see if iBillingProcessor has been instantiated already. If it hasn't, it goes through the process of instantiating it but now it holds onto it because it uses that same instance to feed any other requests for iBillingProcessor
so you get built in singleton capability here. I'll show you that in a second. That's one scenario for instance lifetime. The other one's a little more hairy. The other one is when anything that you're going to resolve from a container implements the iDisposable pattern,
the container is designed to hang onto that object even after your use of it has long gone. The explanation that I get about this is still a little weird for me because what I'm told is that it does that because the container does not know
when you're going to call dispose on it so it wants to hang onto it. But if I'm done using the object, I'm usually under the assumption that I have called dispose on it already so I don't have to worry about that. So I don't want the container hanging onto it. And this can become a problem in a web application with memory leaks because now if you're using,
a good example is WCF proxies which implement iDisposable. I tend to inject WCF proxies into MVC controllers or API controllers. And WCF proxies are already associated to the service contract.
If you've ever done any WCF before, you got a proxy associated to a service contract because that's what it implements. So it's already a perfect candidate for DI because I can register the proxy to the service contract as just a class to an interface. Then my MVC or web API controller can receive a constructor argument of type of the service contract interface
and it'll take care of instantiating the proxy. But then after the request is done and that controller is gone because the web is stateless and it doesn't hang onto controllers, the container, which is stateful, is hanging onto that proxy because it implements iDisposable even if I already call dispose on it. So it doesn't make a whole lot of sense to me but it becomes a problem
because now you start loading up memory with instances that are not used anymore and that's what causes memory leaks. So this apparently is a known thing. I'm not gonna say it's a known problem because the guys that write these containers will tell you it's not a problem at all. I consider it a small problem. I think it could have been handled differently but there is a solution for it and I'll show you what the solution for it is
and every container's got their own different way of doing it. Let me show you the singleton first. I'm going to run real quick the lifetime scope here. Oops, no, hold on.
What did I do wrong? Did I screw something up when I messed up with this demo? What was that now?
Oh, you're right. You're absolutely right. Thank you very much. That means I gotta get rid of that. It was customer processor, right? Now what's another way that I can fix that? I'm gonna comment this out but how else can I fix it? Just register it.
That's it. Register it and let the container take care of what it needs to take care of. Exactly right. By the way, about my and any other authors Pluralsight courses, Pluralsight's got a booth out there
so if you guys need a free 30-day subscription, they'll be more than happy to hook you up with one. Keep in mind, all of the free 30-day subscriptions are only good for watching my courses. Okay, check out what just happened. Everything ran through, no problem. Counter inside a class, I have another class here
called Single Tester. The counter is set to one. I'm gonna run it again. Oops. What's the counter set to? It's set to one. Why is that? Well, huh? No, it's not hard-coded, you smart ass.
All right. Which one is it, commerce three? There's Single Tester, display counter. Single Tester's down here. It just increments counter in the display counter and shows it. So it's class-wide variable being incremented
at the method but both times it was one. I've abstracted out so I can make it testable. As you can see, to use it, all I had to do was add it there and where is Single Tester? There it is right there and register it. But each time it ran, it was set to one.
That's because every time that I ran it, the container is static in memory. It only gets registered once. But every time that I made a call to process order, as you can see, there's two calls right here. It just reinstantiated Single Tester. If I wanted to change that behavior, I can do this.
In AutoFac, all I have to do is add single instance. Every container has this feature. Its syntax is just gonna vary, it's gonna change a little bit. Say again? No.
It holds it, absolutely. As a matter of fact, I'll prove it to you. Single Tester is set to one, it just incremented. It's a class-wide variable, so the same instance of the class has been reused. So the container is in charge of hanging onto it.
Now, the pattern for fixing the disposable problem is, again, differs from container to container. The way AutoFac does it is that AutoFac lets you temporarily create a kind of a sub-container of itself.
And then what it wants to do is it wants you to dispose that sub-container, because then that's when any instances, any instances of dependencies that that container has given you, if any of them are being held onto, because they implement the IDisposable pattern,
then the disposing of the container is what gets rid of those instances. But we obviously don't want to dispose our main container, because we need that for the rest of our application. So AutoFac gives us this sub-container kind of ability, and all I did was build that functionality
into another version of the processor locator. So my original technique was not as cool, but at the same time, I'm gonna show you yet another cool feature of AutoFac. I know it sounds like I'm trying to sell AutoFac. I'm not, use whatever you want. They all have these features.
I'm just used to the syntax with this particular one. But this is the processor locator that you saw before, but what I'm doing is that when the processor locator is instantiating, I'm creating a scope. That creation of a scope is creating the sub-container that I'm talking about in the scope variable. That scope variable is this lifetime scope,
and it's off that scope variable that the getprocessor is going to resolve my dependencies, because then when I'm finally done from the hosting method, when I'm finally done using these dependencies, I need to make a manual call to release scope, and that sub-container that I created gets disposed
without touching the original container. My original technique for creating the scope, the sub-container, was by going to the static class and creating and doing a begin lifetime scope. But I changed it because I wanted to show you one other thing. There may be classes down the road that you write
where you want to actually go to the container and resolve something, okay? And you can do it this way, but there's a lot of people that have a problem with this and I can understand that, because what you're doing is that you're hard coding, you're hard coding your coupling, basically.
You're hard coding something concrete into a class by saying, even by saying go out to the container and get this, like in this case, I'm saying begin lifetime scope, but it can also say program container.resolve to get something. I'm still coupling to the container. AutoFact has a cool feature, and I think most of them have this, where automatically AutoFact, the container itself,
has an abstraction that registers itself in itself, if you kind of get that meaning. I know, it gets kind of weird, right? But the AutoFact container itself implements an interface called I lifetime scope. And because that's automatically registered for you,
AutoFact will resolve that for you. So I've injected, because this class gets injected into commerce, I've injected I lifetime scope into here. So when AutoFact resolves processor locator to, and it sees this, it's gonna say,
okay, what's I lifetime scope registered to? Oh, it's registered to me, the container. So let me just take this container that exists, it's a singleton container, and plug it into there, so I can have access to it, and then this class can now do a bunch of resolves, does it do anything that it needs? Now, I can't do a begin lifetime scope from,
I mean, I can't do a resolve right from this, because this is not a sub-container. I still need to create that sub-container. This is the actual main container, the one that I created all the way the heck up here. It just happens to be made available to you by the container itself.
Do you understand that weird twist to words that I'm using? But it makes it, it's a pretty powerful feature. When I learned about it, which is actually quite late, it was sometime in the middle of last year, I didn't know you can do this, I had, in several classes, I had this kind of stuff here going on,
and instead of scope, I would have this right here, program.container.resolve. And I changed all of that so that anywhere where I had that, I was just injecting this, and now I can just do container.resolve. And the nice thing about it is that I'm programming to an abstraction, so now I can test this class if I wanted to
without being locked into a call to that static method, because it's going off an interface. So it's a cool feature that AutoFact has, and to the best of my knowledge, they all have that to some capacity. I know for a fact Ninja, who are the Ninja users? So Ninja, I think it's called Kernel, am I correct? And Ninja's got an iKernel interface,
so I believe Ninja, you can do that too, you can inject the iKernel interface, and it's the same thing as injecting this, you're injecting the container itself, so you can do resolves from it. Do you have your hand up? Nope. Any questions?
Already did this? Already did that? Okay, there's other ways of doing registration, and I'm gonna show you a couple of them. We got like five minutes left. Is this the last? It is the last. They put me, you know I got off a plane this morning?
And got into the tube, got to the hotel, slept for one hour. So if I mess things up, I may be giving you complete horseshit, okay? It's just from lack of sleep. All right, let me show you other ways that you can do registration. There's, I got a couple of demos on them.
it. I really wish that I had a full 75 minutes. So this is assembly scanning. If you set your classes up with nice naming conventions, which is always a good idea, you decide what the naming conventions are. You don't have to copy mine. If you work with a team
or you head up a team, naming conventions should be a my way or the highway thing, which is don't let your developers run rampant on their own conventions. Establish a set of conventions and ensure that they're followed. In my particular case, I have a hundred dependency
classes in this project. Pretend. But four of them are these processor classes. I set up a naming convention for my processor classes. The naming convention is that there's something, something, something, processor. Very simple. Just for demo purposes, right? So what I did here is that instead of registering all the processor classes one at a time like
this, what I did here, I registered commerce, because I had to, and then I said register assembly types from the following assembly. In this case, it's the executing assembly. But you figure out how you need to get that assembly. It can be off a type, like
a type of something dot assembly. Any type in the assembly will do. I'm going to say of all the types in that assembly, I can use a lambda expression here. Grab me the ones where the name ends with processor, okay, and then I'm going to register them as an interface. Each one of them is going to be an interface. What's the interface going
to be? Well, I'm going to land the expression in, and I'm going to grab for each of the types, whatever type I happen to be in, get the interfaces for it, and grab the interface that starts with the letter I and ends in the name of the type. Just following a naming convention. So billing processor has I billing processor. Customer data repository
has I data repository. In this case, it's just processor, but you understand what I'm talking about when I say conventions. By doing that, I can now add more processor classes and I never have to go in and register them, because I have this one technique
that registers them. That's one example, and the demo is exactly the same as the other one. It just shows you that it works. This is another thing that all the containers have. I only know how to use it in AutoFact, but I know that they all support modules. As you can see here, I'm registering a type, but now I'm registering a module, and that's
it. Why is that? Because I can now break out my registration in different classes, classes that inherit from AutoFact.module, override the load, and in there you get the builder, and now you just do your registration, whether it's this or hard code registrations, whatever you want. But now you can break them up, and I have a module that's my business
repositories, I have a module that's my data repositories, I have a module that's my WCF client proxies. Just a nice way of breaking out your registrations, and also these modules can now come from different assemblies. AutoFact also has the ability,
there's a NuGet package called AutoFact configuration, and what it is is that it's a built-in module whose job it is to go out to the config and reconfig information and grab the type and interface from there. So yet another way of registering it. I see that red light.
Can I have two more minutes, guys? I know one person in particular wants to see this one. So this is one to many. Who was it that asked that question? It was you, right?
So here's building processor, customer, notification, login, processor, and then here's an assembly-type registration where I'm saying go to this assembly and register anything that starts with the word plugin, register it to iPostOrderPlugin. And I have three classes. iPostOrderPlugin,
I think they're just called plugin one, two, and three, if I'm not mistaken. Here we go, plugin one, two, and three. How complicated is that? Each one is simply just going to say plugin number one, executer number two, number three. So by registering multiple classes to one interface, I've just confused the situation because now it's going
to be up to my commerce class to do things the right way. Because if commerce receives an injection of iPostOrderPlugin, just one of them, AutoFact's going to get confused. And every container handles this separately. I think one of the containers, I don't
remember which one it is, will actually default to the first of what is maybe many registrations to that same interface. It'll just take the first one. If you ask for one, it'll give you the one at the top of the stack. AutoFact does not do that. AutoFact will actually tell you, you must tell me which one of these you want. And there's like a string identifier for it, I can't remember how to use it. All of them support
this, which to me is the more common scenario, which is you inject an IEnumerable of that. Because now you have all of the plugins, and now you can do with them whatever you want. And all I'm doing is iterating through the collection and calling and do something. So it's a great technique for doing plugin and modular architecture.
Does that answer your original question? I'm going to skip that because it's rarely
used. I want to get to that one there. This one's very cool. And I cannot tell you if, even if the other containers have this capability. I know that AutoFact does, and it's helped me, and I know that MEF does, because MEF actually forces it on you.
And what I'm talking about is the following. I got a class with more than one constructor. I'm surprised nobody's asked this question. What happens if a class has more than one constructor? Which one is it going to use? Every container does things differently.
AutoFact and Unity, and I think probably most of them, if not all of them, will actually take the constructor with the most arguments and use that constructor. But that may not always be the case, as in my case here. As you can see, this constructor has more arguments than this one. Yet this one is used by, I don't know what the hell this
is used by, somebody else is using this constructor and sending in four integers in there. But this one is depending on dependency injection. However, AutoFact is going to, by default, oops, I should have had this commented out, sorry. So as you can see, you
can do so much more with these containers, more than what we have time for, but you could actually come up with default arguments in case it encounters this A argument, put the number one in there, that kind of thing. But watch this. Watch where it breaks.
It breaks here. Now, AutoFact is automatically going to use this because it's got four constructor arguments instead of three, so it's the one with the most. And it's
going to send in the number one, because that's what I just told the container. When it encounters A, send in a one, B, send in a one, and so on. But then my call is going to go to process order, and it's going to come and run this code. And what's going to happen when it gets there? It's immediately going to break.
Why is it going to break? Because processor locator is null, because that came in through the other constructor. So the point of this last exercise is how do we get deterministic constructor injection, something that, if you've used Mef, who's used Mef before? M-E-F. So you know Mef has got the importing constructor argument. So in Mef, you're forced
to tag the constructor that you want to use, you have to tag it with that. And for people that think that's dirtying up your code, it actually helps you quite a bit because it automatically solves this problem, because you told Mef, I have 15 constructors on. God help you if you've really got 15 constructors, but I got a
boatload of constructors, this is the one that I want the container to use. Well, I want to mimic that scenario here. So I want to do it by using my own very appropriately called awesome constructor attribute. So what is this awesome constructor attribute? Does the awesome constructor attribute solve the
problem for me? It doesn't do anything. A constructor is only as good as that which looks for it. The constructor itself is not doing a damn thing, but something has to be looking for awesome constructor attribute. So what is looking for it? AutoFac has this concept of a constructor finder. So I
wrote awesome constructor finder, and I have to implement the find constructors. This is the type that is about to be resolved, in my case commerce. I do whatever I need to do to determine what constructor to use. In my case, I'm looking for the constructor that's got that attribute.
If you want to say use the first constructor, go ahead. If you want to say if it's a full moon and it's on Tuesday, use the third constructor just to mess with somebody, you can do that too. I say use the one that's got that attribute on it. So now that I got this constructor finder, I can install it like this. Do my registration, but then add
it here. Find constructors with an instantiation of new constructor finder. And that's it. That solves the whole problem, because now when I run this, the constructor that it breaks in is that one.
And my code continues to run and everything is fine. And there's my plugins, by the way. So guys and gals, this is all we have time for. This is actually the last demo without going into the projects,
but the projects are here for you to mess around with. I'm at your disposal. Feel free to email me, Twitter me, whatever, if you need help with this. It's this whole usage scenarios AutoFAC section at the end here. You've got an MVC application, WCF web forms, and WPF, all using AutoFAC and showing you how to use dependency
injection. In WPF, I show you how to do it with view models. In MVC, I show you how to do it with controllers. So it's some pretty cool demos. I wish we had time for them. But the code is all yours. I give the code to the people here. I don't know if they have a site for it or not, but I have a place where they will be
up on, and I can probably do it as early as tomorrow. I don't have to wait until I get home. But go to my website, my company website. There's a downloads link on there, and you'll see a list of conferences. NDC will be the most recent one. And you'll
see the two sessions that I'm doing here on there. And you've got the slides, the code, everything, the demos are laid out pretty good, so I think you can get a lot from them. I'm speaking again on Friday morning, and then I'm flying out Friday afternoon, and I'm doing a talk on how to play nice with ASP.NET, MVC, and Angular. Any Angular junkies here? That's it? What are the rest of you
going to use? Nothing? Anyway, come see me again. I hope you enjoyed this. Please give me an eval at the hopefully there's no red ones left. Actually, I shouldn't have said that. That means that they've been used. But give me an honest eval,
and we use this information quite religiously, so please don't forget. And that's it. Enjoy your day. Hope you enjoy the rest of the conference. Thank you very much.