How to implement Dependency Injection in Mojo?
The following doesnt work (yet) in Mojo it seems
i get the following error:
Is there a way to implement in Mojo what i am trying to do here. As we don't have inheritence yet i want to use Dependency Injection but without this i feel loooooost.
Any advice on this highly appreciated. Not knowing how to implement this discourages me to think of more interesting framework like Mojo projects unfortunately.
5 Replies
i notice that the following works:
but having to specify the struct which confirms with the trait as parameter won't get me far in more realistic examples i am afraid.
I think you are working through an example like "Quackable" here - https://docs.modular.com/mojo/manual/traits#using-traits. A trait is not a concrete type so I don't think it can be used as an argument type. The type can be inferred at the call site though so you don't need to use the square brackets when calling
lets_print
. Lastly there is a note in the link saying they hope to make the syntax less verbose in the future.Traits | Modular Docs
Define shared behavior for types.
oh okay, million thanks, i actually dont have to specify the concrete struct as parameter, the function just has to defined like that, excellent. I completely missed that
for the record, as @Michael Kowalski pointed out, the following works
ok i see now that this does not work
as @Michael Kowalski said, " A trait is not a concrete type so I don't think it can be used as an argument type. " will see how far i come with the new insights here, thanks again
Still not really happy with my understanding, hope someone can help me further with this. Right now I only manage to implement Dependency Injection via struct parameter at compile time. Is there a way to inject dynamically via
__init__
Any advice on this highly appreciated. Thx
here is what i do so far :
This isn't possible and it isn't ever going to be possible with structs. You'll have to wait for classes. The reason for this is that the compiler needs to know the concrete type you're using at compile time because this allows for certain optimizations to happen that aren't present in other OO languages.
Specifically, your PrintManager isn't going to just contain a pointer to a Printer (unless you say it should), it will simply contain all of Printer's fields within itself in a single contiguous chunk of memory. To do this, it needs to know how big Printer is, which could vary between concrete implementations. Additionally, Mojo doesn't use vtables to achieve polymorphism. Determining the specific concrete type at compile time allows the compiler to know exactly what needs to be called when you call a method on that type without any extra work at runtime, which is necessary when using a vtable. This is all part of Mojo's goal of being high performance. Classes will still be able to do all the crazy dynamic stuff though if you don't mind the performance hit.
thanks a lot @Ryulord for these explanations, very helpful for my overall understanding of Mojo and how to design programs 🙏