Dependency Injection in Ecto (via metaprogramming)

Hey, as far as I know, Ecto uses macros and metaprogramming for some sort of Dependency Injection, where the code relevant to each SQL engine is injected into the API/Interface, correct?

I’d like to know why is it really using macros, could be this achieved some other way or is there something in the macros that allowed Ecto to be built that way. Maybe using some sort of makefile would achieve the same thing?

If you are talking about adapters, we do depend on configuration to choose the adapter and call the proper adapter with the Ecto.Query construct. It could be called dependency injection but I would prefer to call it an adapter mechanism.

The configuration part does not use macros per-se, although the query building does since we need to translate Elixir code into SQL and such is best done at compile time.

1 Like

Not an Ecto contributor, but I’m fairly sure that Ecto doesn’t use (much) metaprogramming for translating an Ecto query to a specific DB query language. It’s mostly plain old functions transforming some data (an Ecto.Query struct) to some other data (a string containing a SQL query when using postgres or mysql)

However, Ecto does use quite a lot of meta programming, but that’s for Ecto’s query language itself. Take this simple query for example:

from u in Users, where: u.email == ^"someone@example.com"

If from was function, the u.email == ^"someone@example.com" part would be evaluated before executing from. If we forget for a moment that ^"someone@example.com" isn’t even legal Elixir syntax (which is another reason for using a macro), the result of u.email == ^"someone@example.com" would be either true or false, which would make it impossible to later translate the Ecto query to something like SELECT * FROM users WHERE email='someone@example.com'.

The above explanation may be a bit contrived and certainly not complete, but I hope it shows why it is the Ecto query language that needs macro and metaprogramming.

1 Like

@josevalim yes I meant the adapters. I was under the impression that Ecto used macros to choose and use the correct adapter? Am I wrong in this?

And yes it can’t be called Depedency Injection since that’s a pattern for Object-Oriented and usually means the linkage of components :slight_smile: