Press "Enter" to skip to content

Dependency Injection without classes – Fun Fun Function


good Monday morning today we are going

to look at how you can do dependency

injection without classes using only

functions I am your host npj and you are

watching fun function

[Music]

all right so the viewer that I am a

visioning for this episode is somebody

that is coming from a Java or C short

background and you are used to doing

things in certain ways and you are

wondering if those ways are applicable

to JavaScript and if not how to do them

in a more JavaScript D way yeah that’s

it

and it might also be that you’re just

falling onto this video and you are

wondering what dependency injection even

is and if that’s the case you can check

out this video that I made on the

subject of dependency injection you can

also find that episode in in the episode

that linked to that episode in the

episode description words are hard today

let’s first look at an object-oriented

example of dependency injection the way

you would probably do it f you were new

to JavaScript and you’re jumping into

this and you’re coming from a c-sharp

background let’s imagine that we are

coding a user manager it’s a thing that

for now is responsible for adding users

to the database I’m now going to code

this using my hands

[Music]

yeah I did it

alright let me walk you through this I

just have to start now so say come on

come on come on there there cool

so first line here this is just a

fictitious database the UNICOR database

that I made up on the spot yes like that

app is this is just our main application

we are not going to go through that

because it doesn’t exist I made that up

as well and we have this user manager we

are going to be coding this it doesn’t

exist at this spot quite yet but I want

to show you first how we use it we begin

here by instantiating a new database

connection here we we pass it a host and

a ported some basic configuration

options and we get a connection object

back from instantiating this class and

this this is some some API that we are

getting from the database vendor we have

no control over this or anything we

wouldn’t even have that if it was real

down here on line 10 we are

instantiating

our user manager and we are passing it

the connection object you see see here

this sorry this thing we are we’re

passing it in here and we get of course

a music manager object our username is

your instance of the user manager class

here finally here on line 12 we are

passing in the the user manager that we

created here and we’re passing it into

the constructor of the app our main

piece of code that is dependent on the

user manager it needs it to do stuff and

then it goes away and it starts it or

something this is not terribly important

it’s just to give you some context what

is important is what user manager does

so let’s let’s proceed to write user

manager boom let’s create that file use

now

okay same I’m gonna call that you sir

manager dr. J yes

oh that’s implemented

[Applause]

[Music]

yeah I wrote some code let’s walk

through it it’s a user manager class all

we need to export it as well

exports default user manager otherwise

who can’t get to it from the outside and

then the file doesn’t serve much purpose

in the world anyway it takes a it has a

constructor that takes a database

connection remember from the last code

let me show it to you here the user

manager accepts a connection object

let’s go back that is what it gets here

and it will assign it to a private

private variable private property that

we call underscore connection and we use

it down here but I haven’t typed it

correctly create user here accepts a

name and it will then call table on

users and supposedly get some kind of

object command object of some sort back

from that which we call insert on with

some options I made all of these up its

needs is new here for some ungodly

reason and then we pass the name

property as to the full name property in

there to the insert argument and Edward

seems to return a promise here and when

we when the promise resolves we get a

user and we extract user ID from that so

what great user will do is will it will

create a user where the name that we

pass it and then it will create return a

promise that eventually resolves to the

ID of that user that is what this

fictitious little application does now

let’s rewrite this in a functional way

I’m going to switch back to the main the

starting the application the init main

thing first and what I’m going to do

here is that instead of calling this

user manager I’m

going to call it user utils and we’re

going to call it from user utils because

it’s it’s not really a manager object

it’s going to be a set of functions and

this is no longer going to be

mm-hmm you know one way we are not even

going to have a containable

we just we are just going to have a

create user function and it is going to

be AHA make create user and that is

going to take the connection of like

that and make reducer is going to be

something that we export from the user

utils

whoops sorry about that tasty paste make

create user and then create user is

going to be something that we pass into

the app because the app is dependent on

on create user alright so we are going

to code this thing the user utils next

but before I do I would like to spend a

little bit of time showing some love for

you the patrons the astute of you might

have noticed that there were no ads

running before this video and that is

because your patronage your financial

support has allowed me to turn those off

no more annoying pre-rolls they are gone

now I no longer need to care about

making advertisers happy or keeping the

view counts up I only need to care about

what you the patrons think as of

recording this there are 1465 of you but

there are 13 of you that have been very

generous and selected either the

incredibly stupid paper waste

celebration tier or a higher one and I

would like to celebrate you now

[Music]

I don’t know thank you so much

old patrons thank you so much for your

support you really didn’t have to do

that but you did and that makes you

amazing your support allows everyone to

enjoy fun fun functional free without

ads and it also allows me to pour more

money and more time into fun fun

function and take it to the next level

thank you so much for being a patron all

right back to the code we where we okay

we were creating this user utils and

let’s do that ah you know what I’m going

to grab the user manager copy paste that

and keep it here but commented out so

that you can get a reference compare it

alright cool

BAM okay so let’s have a look at what

this does because this is for some of

you this is going to be absolutely

nothing strange and for some of you that

are probably new to JavaScript this is

going to be super weird what is

happening here

so what make create user does it that it

creates the create user function for us

it’s a is a little factory that creates

the create user function as a bit of

matter but let me walk you let’s jump

back to the example and have a look at

what it does so here we call them a

create user and we pass in connection

and that will give us create user so

when we this create user when we when

app actually does use it inside of

itself it will just call create user dot

o

that name like Mark Smith that’s the way

it’s going to be used so may create user

is a thing that creates create user

functions it’s not even a thing why I’m

not saying a thing it’s a function that

creates other functions that is called a

higher-order function and you can call

like I have an episode on that and the

long functional programming series that

is following it and you can check out it

out by clicking there you can also find

it in the episode description

higher-order functions they are

fantastic either way let’s jump back

into user user utils and see what we

have there

so again may create user it takes a

connection and then it returns this

function it creates this function and

this function it takes name that’s it’s

only variable only argument and then it

uses that inside inside of itself and

you know what I did a copy paste here

this is this is stupid

in the earlier code it would refer to

the the private property connection

the class but we don’t have any class

here we have a connection here as an

argument and we have actually access to

that so connection there and then it

does exactly the same thing as as before

and before because this is an arrow

function and we don’t use curly brackets

here and we we can do that when it’s

only one when and the arrow function is

has only one line then the return

statement we don’t need that because

that is that is implied when we leave

out the the curly brackets so we could

also do it like this turn but we don’t

do that in here because we can save that

and what you’re observing here with

where we access connection this is the

power of closures in JavaScript if you

need to closures I have a video on that

here and you should watch that but a

quick primer is it’s they are so so nice

I’m gonna make a bit of indentation here

to make it perhaps a little bit more

obvious so this first function here the

outer factory function or whatever you

would like to call it it it will create

a new closure so code inside here if if

we had used curly brackets here and it

was there was space for more more

functions so more code I mean anything

here would would have access to the

connection connection parameter of

course that because it’s a it’s a

function and of course the function has

access to it’s it’s its own arguments

but the fantastic thing about closures

is that when we declare another function

inside of a function like connection

here we have access to that the the

argot and whatever the whatever this

function has access to here this code

this code here also have access to the

very same variables and arguments such

as the the argument from the from the

outer function so this is what allows us

to do pull things like this off closures

are really really really powerful let me

go back to the previous annotation level

and this technique that we’re using here

where we are creating a function that it

is kind of prefilled where the the

connection because you know we could

have just done done this but then it

would have been cumbersome to pass

around because then we would have to

pass around both the may create user and

have a reference to the connection

somewhere like this allows us to

pre-fill the the create user with the

connection like like let me go back to

the main code so what we do here is that

we’re creating a function that has we

have a kind of prefilled it for like

loaded it with the connection so it’s a

create user that is tied forever to this

this connection here and that means that

app when it gets a great user it can

just call create user doesn’t need to

know anything about about how the

database has been being accessed because

that is abstracted away inside of create

user it’s a great great way great

example of dependency inversion I have a

video on that as well but I I actually

in that video I call it inversion of

control which is not quite the same

thing I misunderstood subtleties but

what I described there is dependency

inversion and the concept is the same I

just get the labels wrong but either way

I digress let’s look back to this thing

here this technique here the prefilling

of the connection of the name it has a

there is a name for this and it’s called

Korean I do have an episode on that as

well up there or in the episode

description back when I made that

episode I didn’t really fully understand

the need for Korea as much as I do now

and I think that this actually

illustrates the case was better than

that episode did but why would you do

this why you scurrying instead of

classes in order to do dependency

injection why why would anybody prefer

this over classes there are several

reasons but in this case I think the

strongest argument is just the

minimalism functions is something that

we already use in the language closures

is something that we already use in the

language all the time and in this case

we can just get away with not using

classes we we can just not add that to

the toolbox that is our application it’s

one less thing also I would argue that

the current solution is simpler it’s

it’s just simply a lot less code it’s a

bit more a lot more elegant the class is

just a bigger construct even if we even

if like I know that classes are going to

get arrow functions so we could do

something like this and you know that

makes the comparison a bit more fair but

as you see there’s still a bit quite a

bit of extra syntax in this case and

classes also has the extra complexity

that that involves this this is arrow

functions makes it a little bit nicer

but it’s there’s still a bit of

confusion around what the hell this

refers to in JavaScript that’s it’s not

rocket surgery but it’s an added

complication when you compare it to this

case where it’s just incredibly obvious

what what connection refers to and what

it will refer to in all all situations

there

no way of changing changing this while

in this case if this wasn’t an arrow

function this could be like change

depending on what context is was called

classes do in some cases have

performance benefits but those are so

minuscule that they are only in play if

you are creating hundreds of thousands

of objects per second in this case we

are realistically only having a few user

managers as at best so it’s going to

make absolutely zero impact on our

application also it’s just beautiful

look how good it looks

ah but you might wonder what happens

once we start adding more methods to the

class what would be the equivalent there

like let’s say that we had a delete user

or or something like that what would

happen then I will be talking about that

in the next episode

ah cliffhanger you have just watched an

episode of fun fun function I release

new episodes every Monday morning Oh 800

GMT if you are watching from the future

you can check out next week’s video here

otherwise you have to wait till Monday

and in the meantime you might want to

check out my patreon video which talks

about why you might want to become a

patron

I am mpj until next Monday morning sexually

Please follow and like us: