This is why dependency injection is useful

แชร์
ฝัง
  • เผยแพร่เมื่อ 30 มิ.ย. 2024
  • Become a YT Members to get extra perks!
    www.youtube.com/@webdevcody/join
    My Products
    🏗️ WDC StarterKit: wdcstarterkit.com
    📖 ProjectPlannerAI: projectplannerai.com
    🤖 IconGeneratorAI: icongeneratorai.com
    Useful Links
    💬 Discord: / discord
    🔔 Newsletter: newsletter.webdevcody.com/
    📁 GitHub: github.com/webdevcody
    📺 Twitch: / webdevcody
    🤖 Website: webdevcody.com
    🐦 Twitter: / webdevcody

ความคิดเห็น • 133

  • @tomaszchmielnicki8676
    @tomaszchmielnicki8676 15 วันที่ผ่านมา +28

    This feels like a workaround - I mean, you've separated the deletePasswordResetToken, and updatePassword functions, but then you're wiring them together with the tx argument, so they're kind of decoupled, but not really, because they still need to know that they can be ran inside a transaction, so they feel like leaky abstractions. I feel like you could just create a separate changePassword function with its own database calls inside a transaction and it would be fine to have a little bit of code duplication there.

    • @WebDevCody
      @WebDevCody  15 วันที่ผ่านมา +2

      Yeah that’s a good point

  • @JGB_Wentworth
    @JGB_Wentworth 23 วันที่ผ่านมา +10

    Also DI enables unit testing to prevent hardwired classes being instantiated in the constructor so that mock classes can be passed in as needed for testing purposes

    • @krajekdev
      @krajekdev 19 วันที่ผ่านมา +2

      Not necessarily related, but after years of studying and expirimentation I can suggest that mocking should be the exception in ones automatic testing approach. I understand that some classes are really impractical in automatic tests suite, but otherwise one should test mostly at the API level and use as much "real" classes as possible.

    • @liftingisfun2350
      @liftingisfun2350 10 วันที่ผ่านมา

      @@krajekdev In unit tests, you want to mock everything but the actual unit that's being tested. That may be a single method or a single class.
      In integration testing, you want to test the interaction of a unit with another. A class with something else. So you won't use a mock in that case.
      Why? Because the goal of the unit test is to prove that just the logic within the thing you're testing works as expected, *given everything else is working as expected*.
      Integration tests will provethat the interaction between two units, *which are assumed to be tested already*, behaves as expected
      e2e tests will cover the whole system's interactions.
      You want tons of unit tests, reasonable amount of integration, and sparingly use e2e tests

    • @krajekdev
      @krajekdev 10 วันที่ผ่านมา

      @@liftingisfun2350 again, i think that this mantra of tests pyramid is ineffective and i practice approach of reversed testing pyramid. My mocking is very limited.
      I know that youtube comment is not a place for the lecture. I just provide it, because years ago i needed the trigger to free myself from false "test pyramid" paradigm.

  • @domizianoscarcelli1936
    @domizianoscarcelli1936 29 วันที่ผ่านมา +14

    I was in a very similar situation that I didn't know could be resolved with dependency injection, nice!

  • @tjakevladze
    @tjakevladze 22 วันที่ผ่านมา +6

    You can also solve this with the Unit of Work pattern. You add all the operations to the unit of work and when you call the Commit() method, it will create a transaction and process the database queries. What is your opinion on this solution?

  • @shaked1233
    @shaked1233 26 วันที่ผ่านมา

    This is awesome, I never thought about that use case with drizzle. your content is superb, keep em coming!!

  • @tmanley1985
    @tmanley1985 29 วันที่ผ่านมา +2

    Among other things, one thing that dependency injection does is to force you to confront and make explicit your dependencies. When your function signature begins to grow, you may start to notice that it's either too big or data starts to clump together often which usually means that there's either another abstraction you're missing, or perhaps the function has too many responsibilities.

  • @RhettNewton-r7b
    @RhettNewton-r7b 24 วันที่ผ่านมา

    This is awesome! Love seeing clever and clean solutions like this. Thanks for posting this!

  • @vitorfigueiredomarques2004
    @vitorfigueiredomarques2004 29 วันที่ผ่านมา +4

    One interesting thing is that with React context we can easily have an Angular-style DI container so we can control the lifecycle of the injected object instead of just having everything global or passing all dependencies from function to function.
    Create a context whose default value is a WeakMap.
    Now in your application, you can create many providers for this Context that add dependencies to the WeakMap.
    Create a hook so the components can access the WeakMap and pass the WeakMap to your functions.
    Now, for instance, if we want a dependency that needs to load after something shows on the UI and part of the UI needs to show a loading spinner while it is loading, create a Provider that adds that dependency only after it loads (you can use the "use" hook to force some loading screen on the provider).

    • @hebersolano5093
      @hebersolano5093 28 วันที่ผ่านมา +2

      Interesting, you need to make a video about this

    • @brockherion1275
      @brockherion1275 27 วันที่ผ่านมา

      TKDood (maintainer of React Query) writes about this a lot on his blog. He did an excellent article on how to use React Query as your async state manager and React Context as your DI container to use that data elsewhere in your app. It's a pattern I use quite a bit!

    • @twitchizle
      @twitchizle 22 วันที่ผ่านมา

      U should write an example about this.

  • @reallylordofnothing
    @reallylordofnothing 10 วันที่ผ่านมา

    At 2:35 when trx is not sent - as it is optional - what happens at line 75 ? await trx will be null or will db be configured as default if not passed?

  • @Burak-ls5yd
    @Burak-ls5yd 13 วันที่ผ่านมา

    Can you please tell me what is the add-on that shows your Git history on Code?

  • @daphenomenalz4100
    @daphenomenalz4100 29 วันที่ผ่านมา +3

    We can have transactions for both queries as they are both running on a db, but what do i do if first query is an upload to S3, and then second is adding the metadata returned from S3 to the db. If the S3 one fails, that's fine. but if the second db one fails, do we have to make another endpoint for uploading the metadata back to db and asking the client to perform this action again. Since, S3 upload is already successful and we def do not want to rollback that.
    Or is there a better way possible?? Btw love your videos!!

    • @puckwang6850
      @puckwang6850 29 วันที่ผ่านมา +1

      first thing comes up on my mind is retry and put it to a dead-letter queue(if that's not overkill) for the second part of the transaction, but ideally, we want to know the exceptions/errors that cause the failure🤔

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา +1

      I'd personally do it all in a single api endpoint. presigned urls sound cool, but honestly the complexity increases a lot instead of just allowing your api to accept your image and have your api upload to the bucket and also create the db object. you'll be charged more for bandwidth but the simplicity is worth that operational cost imo.

    • @TannerBarcelos
      @TannerBarcelos 28 วันที่ผ่านมา

      ⁠@@WebDevCodyvery much agree here. Since the operations are related, it makes sense to accept the bandwidth overhead in exchange for the simplicity and operational cost that can come out of solving this problem.

    • @daphenomenalz4100
      @daphenomenalz4100 28 วันที่ผ่านมา

      Thnx!

    • @fennecbesixdouze1794
      @fennecbesixdouze1794 28 วันที่ผ่านมา

      Doing it in a single API endpoint doesn't answer the actual question: it's still possible that the upload to S3 succeeds but creating the database record fails.

  • @DemanaJaire
    @DemanaJaire 29 วันที่ผ่านมา +40

    I hate being this early, cause after watching a video like that I like to read what others have to say about it, but there's no comments yet and I will probably forget to come back here. 😭

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา +23

      don't worry I'll send you a message in 8 hours and expect you to come back

    • @daphenomenalz4100
      @daphenomenalz4100 29 วันที่ผ่านมา +6

      @@WebDevCody WebDevChady

    • @KayandraJT
      @KayandraJT 29 วันที่ผ่านมา

      Here's my own opinion on this and sort of a reminder for you.
      This is how I do it, even in other languages I've worked on.
      There's always room to pass in a transaction context and with provision of a fallback for synchronous calls.

    • @puckwang6850
      @puckwang6850 29 วันที่ผ่านมา

      reference it instead of instantiating it, that's pretty much the gist of DI(dependency injection)

    • @louisant1817
      @louisant1817 29 วันที่ผ่านมา +3

      built a chrome extension that reminds you to come back to registered pages

  • @gavipk
    @gavipk 23 วันที่ผ่านมา +4

    Is this really "dependency injection"?

  • @islambn8962
    @islambn8962 29 วันที่ผ่านมา

    and createTransaction function is created so the service ( use case ) does not know about drizzle right ?

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา +2

      yeah I'm not 100% sure I got the abstraction correct because technically the trx object is a drizzle transactions and the use case can see it and know about it in the callback. I think maybe a better abstraction could be runTransaction([doA, doB]), and behind the scenes the trx object would just inject into the last or first argument.

  • @ShivGamer
    @ShivGamer 28 วันที่ผ่านมา +1

    Good catch, I've faced issue regarding this, I was deleting some sessions without checking if the other query was done successfully or not. I had deleted 60ish items from my db in this case while testing, luckily it was stage db so everything was fine😅

  • @wazzadev7209
    @wazzadev7209 29 วันที่ผ่านมา +1

    Thanks for also answering my question 😁👍

  • @brokula1312
    @brokula1312 29 วันที่ผ่านมา

    Why do you await in deletePasswordToken function if there's nothing below await statement?

    • @mostafaelsayed3492
      @mostafaelsayed3492 25 วันที่ผ่านมา

      updatePassword is an async function, it returns a promise, you have to use await to resolve this promise.

  • @brockherion1275
    @brockherion1275 27 วันที่ผ่านมา +2

    Another banger, I'm learning a ton from videos like this! And as I apply these techniques to my own codebase, I've notices my code not only becomes clearer and more maintainable, but I'm also simply writing less code. Keep 'em comin!

  • @gammon9281
    @gammon9281 29 วันที่ผ่านมา

    I would love a deep dive into dependency injection. I'm pretty new to the concept and I've tried refactoring code on a project using the tsyringe containers which didn't work out too well. Are there any resources or guides you can recommend how to (incrementally) adopt DI?
    I liked how i dont have to pass more and more arguments to my functions since the classes were automatically injected into the constructor but that also made it quite hard to split the code / move it outside of the respective classes. Is there a middle ground or a better way of doing this?
    Would love to hear your thoughts and how you think about implementing / adding DI to your codebases

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา +1

      idk I always lean towards injecting with function arguments. Using IoC containers or DI frameworks feels like over engineering and tends to result in code that is hard to understand

    • @gammon9281
      @gammon9281 29 วันที่ผ่านมา

      @@WebDevCody Hey, thanks for the response! I was wondering how you would handle deeply nested function calls. If you have authentication and authorization functions that get called deep inside a big complex function, how would you pass all the different arguments around in that case?

    • @fennecbesixdouze1794
      @fennecbesixdouze1794 28 วันที่ผ่านมา

      JavaScript is a super dynamic language so there's really no need for heavy IOC containers. Just export module-level constants that hold your authentication and authorization and import them into your other modules. Jest allows you to mock all of a modules' exports so there's no need to introduce an IOC framework to make your code unit testable even after you torn out the function arguments.

  • @loorinho
    @loorinho 29 วันที่ผ่านมา +1

    Hadn't gotten much into drizzle and so i didn't even know that they had transactions inbuilt(i guess i need to read the docs beyond making queries). Thank you for the insights. Much love from Uganda "mentor"

    • @bibblebabl
      @bibblebabl 28 วันที่ผ่านมา

      Prisma alternative also has it

  • @Bukosaure
    @Bukosaure 23 วันที่ผ่านมา +1

    What theme are you using for VSCode?

    • @omerelbaz7648
      @omerelbaz7648 22 วันที่ผ่านมา

      Would like to know as well

    • @paulosouza449
      @paulosouza449 16 วันที่ผ่านมา

      This seems to be One Dark Pro ++ (at least to me). I'm not sure though.

  • @bandekhoda7801
    @bandekhoda7801 29 วันที่ผ่านมา +1

    Wow this is super useful

  • @luishenriqueandradepellizz680
    @luishenriqueandradepellizz680 29 วันที่ผ่านมา +1

    So I am working on a transaction feature where it will create a new user account for auth, then create the user own document, in this case an apprentice which will have its own props, then send a registration email.
    I didn’t know how to make this totally clean using SOLID and all this guru stuff then I ended up creating my Transaction class with createTransaction method, which then I Dep Injection the MongoDB session, but then some others dbs do in different way, while Mongo use session, others use different way to manage transactions.
    It worked anyway 😅

  • @tomaszchmielnicki8676
    @tomaszchmielnicki8676 15 วันที่ผ่านมา

    You could also put the database calling functions inside a service object factory with db as an argument, so you'd be able to use dependency injection in every db calling function without modifying its signature, but you'd have to instantiate new objects for transactions

  • @buraky16
    @buraky16 22 วันที่ผ่านมา

    a little unrelated but, which keyboard is web dev cody using? sounds so good. might be brown switch but the sound of key strokes are so smooth

    • @WebDevCody
      @WebDevCody  22 วันที่ผ่านมา

      Klack app

  • @alecdorasandler6690
    @alecdorasandler6690 29 วันที่ผ่านมา +2

    What theme are you using?

    • @alecdorasandler6690
      @alecdorasandler6690 28 วันที่ผ่านมา

      ??

    • @shakapaker
      @shakapaker 23 วันที่ผ่านมา

      It's bearded Theme Stained blue​@@alecdorasandler6690

  • @alderry6447
    @alderry6447 14 วันที่ผ่านมา

    I think best and clean way is using async local storage to shared async context between those methods

  • @reallylordofnothing
    @reallylordofnothing 10 วันที่ผ่านมา

    This is some really clean code. Is this React or Next? Subscribed!

  • @meowmesh
    @meowmesh 29 วันที่ผ่านมา

    is Saas template will be os ??

  • @reallylordofnothing
    @reallylordofnothing 10 วันที่ผ่านมา

    At the heart of dependency injection is "providers can be switched" by simply injecting their dependencies without the called code knowing nothing about providers being switched. In this case, the only switch you can do is either pass the database connection yourself or get it passed by a parent caller. This is more like "pass a default if an object is not passed".
    for it to truly be dependency injection, the trx parameter should have worked lets say "to change password in a redis DB and a Mysql Db via the same methods. If the API for change password and delete tokens is agnostic and providers( redis, MYSQL) can be injected, in my book, that is dependency injection.

  • @derekpowersblight
    @derekpowersblight 29 วันที่ผ่านมา

    I love overloading functions, unfortunately in js es no without arg reading

  • @haruccigr
    @haruccigr 29 วันที่ผ่านมา +1

    I really like that JS devs nowadays wish JS to be more like Java than the chaos it was years ago.

  • @smash3689
    @smash3689 29 วันที่ผ่านมา

    Functions that can be part of an atom. Quark type? Lol. Would it be nice to have such type & have them applied to functions which would make them easier to find & notice?

  • @null_spacex
    @null_spacex 29 วันที่ผ่านมา

    I liked this ✍🏽

  • @jazzdestructor
    @jazzdestructor 25 วันที่ผ่านมา

    this is one of the easiest explanation of dependency injection, thanks Cody, but i still do hate the decorator pattern

  • @supercrunch3367
    @supercrunch3367 29 วันที่ผ่านมา

    Why not just use Nest JS?

  • @Euquila
    @Euquila 29 วันที่ผ่านมา

    I prefer procedural programming more where the control flow and commands are all seen together. The results in a lot more lines of code but you get less indirection and fewer symbols overall

  • @eliotfagnon7319
    @eliotfagnon7319 28 วันที่ผ่านมา

    Does anyone know what's his theme?

    • @WebDevCody
      @WebDevCody  28 วันที่ผ่านมา +1

      Bearded theme stained blue

  • @thomasluk4319
    @thomasluk4319 15 วันที่ผ่านมา

    What colour theme is it

    • @WebDevCody
      @WebDevCody  15 วันที่ผ่านมา

      Bearded theme stained blue

  • @shakapaker
    @shakapaker 23 วันที่ผ่านมา

    That's awesome

  • @sealone777
    @sealone777 29 วันที่ผ่านมา +1

    In this case, it would be nice to use decorator like @Transactional and have the domain code not even be aware transaction exist

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา

      decorators? gross

    • @sealone777
      @sealone777 29 วันที่ผ่านมา

      @@WebDevCody I think you will like it jk. Well I don’t mind it.

    • @salman0ansari
      @salman0ansari 29 วันที่ผ่านมา +1

      over complicated

    • @nazarshvets7501
      @nazarshvets7501 29 วันที่ผ่านมา

      no, it wouldn't

  • @SeibertSwirl
    @SeibertSwirl 29 วันที่ผ่านมา

    Good job babe!

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา

      thanks beautiful!

  • @ironhunter2219
    @ironhunter2219 22 วันที่ผ่านมา

    Cool, I have been using dependency injection without knowing what it is or why it exists xD

  • @ivorhoulker3646
    @ivorhoulker3646 29 วันที่ผ่านมา

    This is a useful concept, but in this case with drizzle it seems not to make any difference: "The tx object passed to the transaction function is just a convenience. You can use db interchangeably, it won't make a difference. It only has a rollback() method which only throws an error. Inside the transaction, it stops execution and rollsback"
    I realise this is not documented well. I did link to the github issue where this quote comes from, which I guess is why youtube deleted my comment. It's issue 613.

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา

      good thing to point out!

  • @Skuiggly
    @Skuiggly 28 วันที่ผ่านมา

    funny watching this after reading your tweet “hating” on dependency injection

    • @WebDevCody
      @WebDevCody  28 วันที่ผ่านมา

      Keep em guessing

    • @ward7576
      @ward7576 25 วันที่ผ่านมา

      @@WebDevCody typical youtuber - explains nothing with a response, just to drive interactions up when otherwise content is quite shit and cannot do it organically

    • @WebDevCody
      @WebDevCody  25 วันที่ผ่านมา

      @@ward7576 I hope you have a blessed day

  • @ajzack983
    @ajzack983 29 วันที่ผ่านมา

    Good old transactions always good for endpoints that no 2 users can hit at the same time

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา +1

      it's all about risk mitigation. Will the second call to the database fail? probably not, but if it does, now your system is left in a strange state

    • @ajzack983
      @ajzack983 29 วันที่ผ่านมา

      @@WebDevCody I used it once on a controller that had a lot of related operations many users can hit the same resource, I ended up with a race condition exception where multiple users try to access a locked row or table even.
      You need to handle that case manually with a retry or something.
      Usually transactions are good for short operations like 2 fast queries are probably fine.

  • @miauw8762
    @miauw8762 5 วันที่ผ่านมา

    This is just a fancy word for a simple solution

  • @sameurbenhmouda1456
    @sameurbenhmouda1456 29 วันที่ผ่านมา +1

    I mostly use this kind of trick but I never knew that it was called "dependency injection". Now I know the technical word, thanks!

    • @federicobau8651
      @federicobau8651 24 วันที่ผ่านมา +1

      Is not dependency injection..is still passing and argument..dependency injection is very different and has a different endgoal.

  • @berkancetinkaya3520
    @berkancetinkaya3520 22 วันที่ผ่านมา

    I would not recommend to call trx as second argument or third one.
    what if I need to pass another argument into this function? it would be like
    token: string, trx: db, emailCode: string
    this is so ugly
    so instead have a structure to pass params for such use cases functions
    { deps: { trx }, input: { emailCode, token } }
    in this way you can easily extend without having argument hells like
    removeToken(token, false, null, 2, undefined)

  • @balduin_b4334
    @balduin_b4334 29 วันที่ผ่านมา

    bruh drizzle is so much better than prisma...
    I wanted to also enable this type of dependency injection, but the type of the prisma client and the transaction prisma client aren't the same. That's why It is not Possible to just say (...., db = dbClient) {...} and the call it with ( ...., tx)
    [EDIT]: Solution
    type DB = Parameters[0];
    then use DB type like that ( ..., db: DB = dbClient)
    You can't use the following functions from the default Prisma Client: "$connect" | "$disconnect" | "$on" | "$transaction" | "$use" | "$extends"

  • @mohammedbageri1678
    @mohammedbageri1678 26 วันที่ผ่านมา +2

    Dependency injection in functional programming 😂. That's just a fancy way to say “calling a function with parameters”.
    Good idea though 👍🏻.

  • @rariber
    @rariber 12 วันที่ผ่านมา

    Maybe I'm being nitpicky, but it seems to me what you have done was inversion of control, not exactly a DI. But awesome content anyway dude, keep it up.

    • @WebDevCody
      @WebDevCody  12 วันที่ผ่านมา

      So in your opinion, what would make this dependency injection if injecting the dependencies as arguments instead of importing them is not dependency injection in your opinion. I think there’s a misconception that you have to use some type of injectable auto wiring dependency injection framework for you to achieve dependency in injection and I don’t think that’s true.

    • @rariber
      @rariber 12 วันที่ผ่านมา

      @@WebDevCody Yeah, you're right, I may have understood it poorly.

  • @tomaszchmielnicki8676
    @tomaszchmielnicki8676 15 วันที่ผ่านมา

    Or maybe use partial application for those two functions and don't clutter their signatures
    export const deletePasswordResetTokenWithTx = (tx: typeof db) => (token: string) => ...
    export const deletePasswordResetToken = deletePasswordResetTokenWithTx(db)

  • @TallStack-su8sq
    @TallStack-su8sq 29 วันที่ผ่านมา

    theme name?

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา

      bearded theme stained blue

    • @TallStack-su8sq
      @TallStack-su8sq 29 วันที่ผ่านมา

      @@WebDevCody thanks

  • @mandokir
    @mandokir 17 วันที่ผ่านมา

    Dear God, he's using JavaScript on the backend.

  • @anothermouth7077
    @anothermouth7077 29 วันที่ผ่านมา

    Person suggesting this must be from Java background 😄

  • @fennecbesixdouze1794
    @fennecbesixdouze1794 28 วันที่ผ่านมา

    I know this video is supposed to be about dependency injection and not about the actual use case ....
    however when you think about the actual change-password use case, it's probably better to not put this in a transaction if possible. For example, if the business logic allows the user to simply request another password reset token, it's perfectly OK to have deleted the password reset token and then failed to update the password: simply present an error to the user and have them request another password reset token.
    Another option is to simply mark the password reset token for deletion without actually deleting it, and have another process come in later and clean up all of the tokens that have been marked for deletion. That way the client can simply retry within some reasonable timeframe (keep in mind that if you do this, you probably want to include information about the current hashed password on the reset token itself so that the same password reset token cannot be used to successfully change a password twice).
    In general, my advice is to avoid transactions like the plague. They really slow down the performance of a web server, and usually you can design around the need for transactions by just thinking a bit more about your high-level design. Also transactions inhibit flexibility in the future: for example if you've designed with the assumption of transactions, what happens when you need to put some logic that interacts with services outside the database into a transaction context? Just putting a bit more thought into the high level design to come up with a solution that doesn't use transactions can save you so much headache down the line, and it's really worth it in almost all cases.

    • @federicobau8651
      @federicobau8651 24 วันที่ผ่านมา

      I think you are in the wrong path. Even think that transaction can slow performance down is...not that correct.
      Transactions ensure consistency and correctness. Just read what you wrote and it confirms this.
      You would avoid use transaction for "some weird reason" and possibly ending up..do a clean up later?😂 that's crazy.

  • @antidegenerates7449
    @antidegenerates7449 7 วันที่ผ่านมา

    Why engineers keep creating problems on empty space and complicate everything?

    • @WebDevCody
      @WebDevCody  7 วันที่ผ่านมา

      Because it’s fun

  • @MrDevianceh
    @MrDevianceh 29 วันที่ผ่านมา

    Huh I thought it's pronounced Lu-Chia

    • @WebDevCody
      @WebDevCody  29 วันที่ผ่านมา

      🤷‍♂️ no clue

    • @liu-river
      @liu-river 29 วันที่ผ่านมา

      The Italian pronunciation is luchia, so it depends.

  • @saburex2
    @saburex2 16 วันที่ผ่านมา

    My eyes are bleeding

    • @WebDevCody
      @WebDevCody  16 วันที่ผ่านมา

      Maybe see your dr about that one

    • @saburex2
      @saburex2 16 วันที่ผ่านมา +1

      @@WebDevCody my doctor can't help with your code, I don't think anyone can... posting a video where you shit on SOLID and call it dependency injection...

    • @WebDevCody
      @WebDevCody  15 วันที่ผ่านมา

      @@saburex2 getting away from OOP is the first dosage of medicine

  • @edgarmagalhaes18
    @edgarmagalhaes18 9 วันที่ผ่านมา +1

    This is not dependency injection, wtf 🤣

    • @WebDevCody
      @WebDevCody  9 วันที่ผ่านมา

      Java dev spotted

  • @ikbo
    @ikbo 28 วันที่ผ่านมา +12

    This is poor man's dependency injection. Real programmer's use DI containers.

  • @federicobau8651
    @federicobau8651 24 วันที่ผ่านมา +4

    Thats not dependecy injection... you are simply passing an argument to a function and still is..
    Simply that.
    Doing that manually doesnt create a dependency injection.
    Then tell me what's the difference between dependency injection and pass and argument around ? 😂
    Dependency injection is more complex and you can do it with a language like Typescript via Interfaces (but using a simple class would do too).
    You are confusing what is it and what is for...
    Yes it may look like is passing an argument into "something" (can be a functiom/method or a class constructor) but the concept and end goal is very different

    • @WebDevCody
      @WebDevCody  24 วันที่ผ่านมา

      it's called functional injection. There are different ways to achieve dep injection. people using OOP like to do constructor injection, some people using IoC containers, some use setter functions, some use a DI framework. the point of DI is that your concrete implementation doesn't know where the dependency is coming from (it's passed in somehow).
      the only part I'd argue that yes maybe this isn't pure DI is because I'm using a db instance as a fallback inside the persistence function, but you're wrong in saying passing the dep as a function argument is not DI. Search how people do DI in functional programming languages. Often it's passed in as a "context" object.
      If you're still not convinced, I took my code and passed it to GPT which responded with this:
      "Yes, the trx parameter in your updatePassword function can be considered a form of dependency injection. In this context, trx represents a database transaction object, and by default, it is set to database. By allowing trx to be passed as an argument, you are injecting the dependency (the transaction object) into the function."

    • @federicobau8651
      @federicobau8651 24 วันที่ผ่านมา

      ​​@@WebDevCody even so it should be implemented differently. The "injection" means that is the "framework" doing it "automatically"... you are not injecting it, you didnt create an interface nor your are calling "a different class" from the original ...you simply switch from the "database connector" to... "the SAME conction but is an open transaction".. so you cant state this is called DI because a poor.. almost non-existant implementation of it .and.. the CALLER IS ADDING THE DEPENDENCY!. So in not "injected".. you manually are adding it ..
      On top of it...you didnt create and interface (and you are using Typescript..so no excuses) and you didnt add the interface type in the parameter...which is basically the main component of DI..so even like this your example. A part of not showing real DI is even very poor example...
      PS: ChatGPT while being great.shouldn't (yet) being considerated a safe place to get answer...is a good start for sure an most of them are somewhat correct but..it does still LOTS of mistake so i wouldnt even brag about it as to say "ChatGPT answered this so is correct"

    • @federicobau8651
      @federicobau8651 24 วันที่ผ่านมา

      ​@@WebDevCody
      So then a question for you, tell me:
      What's the difference on what you did compared to .. passing variable to a function?

    • @WebDevCody
      @WebDevCody  24 วันที่ผ่านมา

      @@federicobau8651 the function prior depended on a drizzle db object (implicit interface) which was used from a direct import at the top. Passing it in as a function argument allows any object that extends that implicit interface to be used as the dependency instead. An argument to a function is not a dependency, it’s just a parameter. Importing a third party library or another module from your codebase is a dependency. If the module is dynamically passed in, you’ve done dep injection

    • @federicobau8651
      @federicobau8651 24 วันที่ผ่านมา

      @@WebDevCody first you are answering what i asked. Second.. emhh.. "emplicit" for the "interface of a DI"..is totally against what DI is for (one of few) and you really want to have it Explicit.
      Third, you are confusing a Dependency...you are calling a dependency "3rd party library" which is dependency of a Project..in DI (and SOLID/Clean code) dependency means..something else..you tottaly can have a something that is a dependecy in you code base..even on the same file XD..dependency here we mean "what the entity depends on" regardless of the source.
      Having said that, both your explanation and the code you wrote...while has some components used in DI..Is NOT ENOUGH and doesnt automatically make it DI.
      Dont take me wrong, i think your code is correct nor i am suggesting to use a typical DI (which many cases is ..overengineerng) in fact i think is the right thing to do but, nope you can't call that DI..no no no..and then if you have found this info online then..well means is a very confused and misunderstood topic.
      If you follow what you explain than...literally ANYTHING that is an object of some sort passed as argument of a function (or constructor) is ..dipendency injection? Common this is Ridículos.
      Then why isnt this already called DI on a 5th lesson of a beginner programmer of (most) programming languages when you first study how to declare and call a function? Why is a DI only found in a broader context like a library or lets say a web server?
      I tell you why.. because those 2 AREN'T the same thing.
      What you have done is pass an object to a function as argument which has a default value. Yes default value is different than the one you passed. Yes both have a method with same name but that ISNT DI.
      So you are telling me that, if you have a function called "count" with param fn that calls it as fn.count ..and you pass as argument an array of strings..or an object.. or a custom class thst has a method count..you call that DI :D
      ..common now..

  • @eliotfagnon7319
    @eliotfagnon7319 29 วันที่ผ่านมา

    Owww what is your vscode theme?🥹