
watching fun fun function a couple of
weeks ago I made an episode where we
explored dependency injection today’s
video is going to be a follow-up to that
dealing with inversion of control at the
end of the video about dependency
injection I talked about some of the
caveats with dependency injection one of
the caveats that I talked about in that
video was the trickiness in getting your
dependencies to the code that wants
those dependencies injected in in the
context of a larger application as it
happens a viewer has provided us with a
fantastic example Vasil burro vehic sent
in this piece of code asking how to deal
with this problem this code is just a
fantastic example of of the problem that
I’m talking about
alright so Bessel has here the store
document function that we would like to
add unit tests for we want to make this
thing testable before getting into
inversion or control or anything like
that yet let’s just get a feel for this
code and what this does so store
documents it takes a user ID it takes a
folder location and it takes a file
stream we don’t have more information
than this piece of code so I am going to
get that file stream is is something
that is from an upload form in an
interface and folder location is the
location where we want to store the file
and the user ID is well the
authenticated users the user ID it takes
that and it passes it to this method
here on the user DB object called find
one and it also does the same thing with
the folder location here Wow
it passes it to find one on the folder
DB so like here is it’s basically
fetching the database
quiver length of the user ID and the
folio location it uses promised at all
to wait for both of those to be resolved
and these two return which are promises
there I have an episode on promises if
you are unfamiliar with how they work
eventually promised that all will
resolve into the actual user in the
actual folder here then it goes on and
checks using the can write method on the
user access object if the the user is
allowed to write to this folder this
users connectors can write it resolves
into an allowed value here and if it is
not allowed it will it will reject using
a boom forbidden error I think I’m just
going to remove this because it just
confuses links boom sa HTTP library for
for for doing like HTTP friendly errors
that can be passed up the chain but it’s
not relevant for this example I’m just
going to do it like exception it went
wrong there we go and why not quickly
wings if the user is allowed to write
this directory it goes on to call save
here on the file storage it also passes
a user and folder to as arguments to
save however there’s a mistake here
because user and folder or are not in
scope inside of this this function here
so I’m going to fix that actually there
now it’s correctly scoped and we have
access to user and folder that’s not
important to the example per se I just
wanted to fix the error in the last
epoch
are we demonstrated a very simple
injection example I’m going to show it
to you now not going to go into this we
talked about this in detail on the last
episode but we this code here let’s get
animals it only has one dependency and
we we inject that single dependency and
this this store document this has quite
a bit more dependencies it relies on a
lot of external code so you have the
user DB you have a solo DB you have the
user access object and you have the file
storage so if we use the same technique
this this thing the signature of of
store document it would it would get
free rocks it would it would look
something something like this
hang on and it would get like user
access and get like file storage so you
would have inject all of these things
and when you called it right function
like store it all human you’d have to
pass all these things in and then do
like the user ID the the folder for the
location you know and then then pass the
actual file stream object file stream
and let’s imagine that this thing is
what it’s inside a view somehow looks
like they could imagine this to be
anything like a reactor or some angular
thing or whatever like something that
renders stuff probably saying that
contains the form now suddenly this
thing would have to be responsible for
injecting all of these things and
perhaps like how do you do that like
either you you have to instantiate them
in this in
this context here like new user DB or
something like that perhaps and do the
same thing with the other stuff like but
then you will get a testability problem
with the view
so perhaps you don’t do that perhaps
instead you you do like you start doing
this like passing all of these things
down but this this is like this is
completely unfeasible because it’s
cumbersome even now with just two lines
of code and and one dependency like just
imagine like if you have ten of these
and you have to instantiate and like
pass every single dependency that is
used by anything down your tree it’s yes
and this is where inversion of control
comes into the picture
so whew whew doesn’t really want to be
concerned with with all of these things
it does need a way to store documents
but it doesn’t really want to you want
to it wants to have its document store
to have batteries included right so the
way we deal with this is to create this
log I function store document factory
and yeah so this function is a factory
of store document functions it produces
store document function and in order to
do that it needs these needs the
dependencies that a store document
function needs kind of take them in
there and what it does is that it just
takes store documents just bind and we
don’t care about this scope so we are
personal for the first argument and then
we just have these guys if you happen to
be unfamiliar with how bind works you
can check out this video that I made on
the topic so what bind does here
is that it’s going to create a new
function create and return a new
function that has bound the first
arguments here to whatever values we
would pass in here to the store document
Factory I will get back to that but I’m
going to just show you how how it’s how
it’s used
to give some context so let’s imagine
that we have our main dove GA s here the
thing that starts your entire
application off the one that creates the
the view here so it does like view and
the view want something it one the view
one store documents just once the store
documents it doesn’t want all of these
things it doesn’t want to be concerned
with that there so you see here that
it’s view now expect to get a store
document function but it’s it’s kind of
like this batteries included store
document function where you don’t need
to pass all of these dependencies in
that is what we use this this bind
document factory and let’s say yeah
let’s say like we have imported these
here like what and it requires all of
these hang out there sits there there
and this will now be a to work document
then I would pass that into the view
just to give you an idea let’s imagine
that import view from you don’t say yes
we imagine that this here this is the
view don’t you as we just do export it
for watching you and you have to like
imagine lots of view logic here let me
clear out this white space here there
and in the same way let’s imagine that
this is another file not sure what we’re
going to call it like store document
perhaps tour document is and we import
import store and don’t go and factory
from the word don’t experiment and let’s
say that we export export this ok that’s
a lot of code let me walk through really
slowly with you what the hell happened
here let’s begin here in Maine dot J’s
so in an application that uses inversion
of control the root level of your
application is the part of your
application that is responsible for
doing all of all of the injecting
happening in the app so it imports the
store document factory here and it also
imports all of the dependencies that it
knows that the store document factory
needs and then it uses the store
document factory to create a store
document function by passing all of the
dependencies that stored up in factory
wants and now we have this store
document function that is ready to go it
has batteries included and we pass it
down into the
you which needs a store document
function in order to save its stuff so
you see here that view it gets a store
document function but even though the
store document function here actually
has way more arguments it has the seven
arguments and still we’re able to call
it here with just with just three and
that is because the store document
Factory has already welded that on by
using bind here which well seize this
functions onto a new function new
variant of store documents that have
these first four arguments always
appended kind of like a– batteries
included caliphate there’s a new feature
in javascript called the structuring i
have an episode on that there that you
can use to make this thing a little bit
less verbose if I add curly bracket here
in curly bracket here now that means
that the first argument to the store
document function is a dependencies
object like it’s an object where that
you expect to have these these
properties and that means that I can
just do like this depth bonk bonk bonk
bonk bonk bonk bonk bonk bonk bonk bonk
and yes do this here that’s there that
there huh that’s a lot cleaner if you
don’t like the store document factory
naming you can perhaps call it create
store document instead the exact wording
and and syntax of these things that is
not what is important I’m just showing
it to you here in order for you to get
some idea of how how kind of works in
real life but what is important is the
principle so we have main J’s here drawn
mange as a person for some reason you’d
like
perhaps because it is the controller the
boss of the application that gets
coordinates puts everything together so
when main gas start setting up the
application it starts by creating this
stored document store document function
and the reason it does that is because
main.js knows that the view will need a
store document otherwise the view you
can’t handle file uploads in the view if
you don’t main j/s is also where that
store document needs a couple of things
in turn to work so in the example that
we saw before these this is the user DB
and the folder DB and the yeah the user
access thing and these are injected into
the store store document in the code
before we had this factory function that
made this a little bit easier for manger
but from a conceptual standpoint the
responsibility might as well have been a
minge as it doesn’t matter too much
and once main DF has created the store
document function it is injected into
the view so now it’s there inside the
view all meaning cozy so the view now
have access to this batteries included
store document the view does not really
care at all about these three these
dependencies here like from the views
standpoint from the views point of view
this – well have been applied it’s just
a black box that it can call to store
documents and this is what it’s referred
to when you say inversion of control
like now the view is no no longer
concerned with the details of the
implementation that has been abstracted
away up here into main Jaya so it has
been control has been inverted
so now I hope this makes sense to you if
it didn’t that’s perfectly okay this is
a bit mind-boggling sometimes you post a
question down below and I or a fellow
viewers shall answer your question and
that’s it you have watched the episode
of Paula Zahn function
release these every Monday morning Oh
800 GMT time but you will forget that in
order to not miss the next episode you
can click the little bell next to the
subscribe button in the YouTube app to
enable notifications this episode was
pretty technical I also have this
software musings episodes that we might
want to check out or this episode which
YouTube says is machine learning but
really it’s arbitrary I am nvj until next Monday morning thank you