Nested Dependency Injections

#1

Hiya

Is it possible for a dependency to further depend on another? E.g.

class FooInjection(DependencyProvider):
    ...

class BarInjection(DependencyProvider):
    foo = FooInjection()
    ...

class Service:
    bar = BarInjection()

Thanks

0 Likes

#2

Hi,

Yes, via what's called a 'shared extension' (behaves slightly differently
but same principle). see
e.g. https://github.com/nameko/nameko/blob/master/nameko/web/server.py for
an example

let us know if anything's unclear or you need more pointers

best,
david

···

On Wednesday, 15 March 2017 10:51:44 UTC, simon harrison wrote:

Hiya

Is it possible for a dependency to further depend on another? E.g.

class FooInjection(DependencyProvider):
    ...

class BarInjection(DependencyProvider):
    foo = FooInjection()
    ...

class Service:
    bar = BarInjection()

Thanks

0 Likes

#3

that's worked out nicely. Thanks David.

···

On Wednesday, 15 March 2017 10:57:47 UTC, David Szotten wrote:

Hi,

Yes, via what's called a 'shared extension' (behaves slightly differently
but same principle). see e.g.
https://github.com/nameko/nameko/blob/master/nameko/web/server.py for an
example

let us know if anything's unclear or you need more pointers

best,
david

On Wednesday, 15 March 2017 10:51:44 UTC, simon harrison wrote:

Hiya

Is it possible for a dependency to further depend on another? E.g.

class FooInjection(DependencyProvider):
    ...

class BarInjection(DependencyProvider):
    foo = FooInjection()
    ...

class Service:
    bar = BarInjection()

Thanks

0 Likes

#4

A follow up question.

Now that it's a SharedExtension, the worker factory does not substitute it
with a Mock when it's on the service class.

How do I handle this?

Thanks

···

On Wednesday, 15 March 2017 11:49:48 UTC, simon harrison wrote:

that's worked out nicely. Thanks David.

On Wednesday, 15 March 2017 10:57:47 UTC, David Szotten wrote:

Hi,

Yes, via what's called a 'shared extension' (behaves slightly differently
but same principle). see e.g.
https://github.com/nameko/nameko/blob/master/nameko/web/server.py for an
example

let us know if anything's unclear or you need more pointers

best,
david

On Wednesday, 15 March 2017 10:51:44 UTC, simon harrison wrote:

Hiya

Is it possible for a dependency to further depend on another? E.g.

class FooInjection(DependencyProvider):
    ...

class BarInjection(DependencyProvider):
    foo = FooInjection()
    ...

class Service:
    bar = BarInjection()

Thanks

0 Likes

#5

Can I even use a Shared Extension on the service class like this?

···

On Wednesday, 15 March 2017 13:46:27 UTC, simon harrison wrote:

A follow up question.

Now that it's a SharedExtension, the worker factory does not substitute it
with a Mock when it's on the service class.

How do I handle this?

Thanks

On Wednesday, 15 March 2017 11:49:48 UTC, simon harrison wrote:

that's worked out nicely. Thanks David.

On Wednesday, 15 March 2017 10:57:47 UTC, David Szotten wrote:

Hi,

Yes, via what's called a 'shared extension' (behaves slightly
differently but same principle). see e.g.
https://github.com/nameko/nameko/blob/master/nameko/web/server.py for
an example

let us know if anything's unclear or you need more pointers

best,
david

On Wednesday, 15 March 2017 10:51:44 UTC, simon harrison wrote:

Hiya

Is it possible for a dependency to further depend on another? E.g.

class FooInjection(DependencyProvider):
    ...

class BarInjection(DependencyProvider):
    foo = FooInjection()
    ...

class Service:
    bar = BarInjection()

Thanks

0 Likes

#6

that's certainly not what they're designed for. may work incidentally but
probably not

shared extensions are for other extensions to depend on, not for services

in your original example, only `FooInjection` should be a shared extension

d

···

On Wednesday, 15 March 2017 13:53:10 UTC, simon harrison wrote:

Can I even use a Shared Extension on the service class like this?

On Wednesday, 15 March 2017 13:46:27 UTC, simon harrison wrote:

A follow up question.

Now that it's a SharedExtension, the worker factory does not substitute
it with a Mock when it's on the service class.

How do I handle this?

Thanks

On Wednesday, 15 March 2017 11:49:48 UTC, simon harrison wrote:

that's worked out nicely. Thanks David.

On Wednesday, 15 March 2017 10:57:47 UTC, David Szotten wrote:

Hi,

Yes, via what's called a 'shared extension' (behaves slightly
differently but same principle). see e.g.
https://github.com/nameko/nameko/blob/master/nameko/web/server.py for
an example

let us know if anything's unclear or you need more pointers

best,
david

On Wednesday, 15 March 2017 10:51:44 UTC, simon harrison wrote:

Hiya

Is it possible for a dependency to further depend on another? E.g.

class FooInjection(DependencyProvider):
    ...

class BarInjection(DependencyProvider):
    foo = FooInjection()
    ...

class Service:
    bar = BarInjection()

Thanks

0 Likes

#7

What is your usecase for this, Simon?

···

On Wednesday, March 15, 2017 at 1:59:12 PM UTC, David Szotten wrote:

that's certainly not what they're designed for. may work incidentally but
probably not

shared extensions are for other extensions to depend on, not for services

in your original example, only `FooInjection` should be a shared extension

d

On Wednesday, 15 March 2017 13:53:10 UTC, simon harrison wrote:

Can I even use a Shared Extension on the service class like this?

On Wednesday, 15 March 2017 13:46:27 UTC, simon harrison wrote:

A follow up question.

Now that it's a SharedExtension, the worker factory does not substitute
it with a Mock when it's on the service class.

How do I handle this?

Thanks

On Wednesday, 15 March 2017 11:49:48 UTC, simon harrison wrote:

that's worked out nicely. Thanks David.

On Wednesday, 15 March 2017 10:57:47 UTC, David Szotten wrote:

Hi,

Yes, via what's called a 'shared extension' (behaves slightly
differently but same principle). see e.g.
https://github.com/nameko/nameko/blob/master/nameko/web/server.py for
an example

let us know if anything's unclear or you need more pointers

best,
david

On Wednesday, 15 March 2017 10:51:44 UTC, simon harrison wrote:

Hiya

Is it possible for a dependency to further depend on another? E.g.

class FooInjection(DependencyProvider):
    ...

class BarInjection(DependencyProvider):
    foo = FooInjection()
    ...

class Service:
    bar = BarInjection()

Thanks

0 Likes

#8

Hello,

here at Namecheap, we’re exploring nameko to be used as our core framework for the microservices.

And I got the exact same question as simon_harrison

An example use case might be a repository pattern.
What if we wanted to use repository pattern for example with nameko-sqlalchemy extension?

class UserService:
    user_repository = UserRepositoryInjection()

    # ...

class UserRepositoryInjection(DependencyProvider):
     def get_dependency(self):
        # how to get Database() dependency of nameko-sqlalchemy in here?
        db = Database()

        return UserRepository(db)

class UserRepository(object):
    def __init__(self, db: SQLAlchemy):
        self.db = db

    def find(self, id: int):
        return self.db.query(User).find(id)

In other words: I didn’t find a way how to properly inject SQLAlchemy dependency into the UserRepository dependency.

0 Likes

#9

Hi Titas,

To implement the Repository Pattern you would subclass Database rather than DependencyProvider:

from nameko_sqlalchemy import Database

class UserRepositoryInjection(Database):
    def get_dependency(self, worker_ctx):
        return UserRepository(super().get_dependency(worker_ctx))

class UserRepository(object):
    def __init__(self, db: SQLAlchemy):
        self.db = db

    def find(self, id: int):
        return self.db.query(User).find(id)

We used this pattern at Student.com to inject higher level abstractions into the services, rather than just the bare session. Worked great.

Do the responses to Simon’s question above make sense? Happy to elucidate or give examples for other usecases.

0 Likes

#10

Hi Matt,

thank you for such a quick reply.
Your solution looks nice and clean!

Just one more thing that got in my mind regarding this strategy.
What if a service depends on 2 repositories. Doesn’t it mean that Database dependency would be constructed twice? Can it be a problem and should we care?

0 Likes

#11

If a service depends on two repositories I would want them exposed separately to the service, and wouldn’t worry too much about the Database dependency being constructed twice.

If both repositories share the same underlying schema, you can probably configure Sqlalchemy to use a single shared connection pool. I’ve not actually tried this but it looks like it’s possible.

0 Likes