# Dependencies between dependency providers?

**URL:** <https://discourse.nameko.io/t/dependencies-between-dependency-providers/397>\
**Category:** Uncategorized\
**Created:** [February 6, 2019, 3:47pm UTC](https://discourse.nameko.io/t/dependencies-between-dependency-providers/397 "2019-02-06T15:47:14Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielrs](https://avatars.discourse-cdn.com/v4/letter/d/3da27b/32.png) [@danielrs](https://discourse.nameko.io/u/danielrs)\
**Post date:** [February 6, 2019, 3:47pm UTC](https://discourse.nameko.io/t/dependencies-between-dependency-providers/397/1 "2019-02-06T15:47:14Z")

</div>

Is it possible fro one dependency to provider to depend in another dependency provider? Similar to what can be achieved in Pytest with fixtures (fixtures can use other fixtures).

In my case I have two dependencies:

1. Provides a Cassandra connection with a default keyspace.
2. Uses the Cassandra connection to run some initialization during the ‘start’ method, and provides a function that is used in my application. It would be nice to be able to use the dependency provided by #1.

I could create another dependency that uses either composition or inheritance, but the ‘get\_dependency’ method still needs to return one or the other. What is a common and nameko-ish way of solving cases like these?

---

<div class="post-metadata">

**Author:** ![danielrs](https://avatars.discourse-cdn.com/v4/letter/d/3da27b/32.png) [@danielrs](https://discourse.nameko.io/u/danielrs)\
**Post date:** [February 8, 2019, 2:57pm UTC](https://discourse.nameko.io/t/dependencies-between-dependency-providers/397/2 "2019-02-08T14:57:54Z")

</div>

**Disclaimer:** Code shown here is not tested.

Figured out a half-solution after reading this:

> [@Entrypoints, Services and Dependencies](https://discourse.nameko.io/t/entrypoints-services-and-dependencies/385/2):
>
> Hi. Sorry for the late reply to this. These questions come up quite a lot. It is fairly common to have a service interface that requires more than one external system, and we ought to have a page in the docs that explains how to do it. You can do this if you’re happy to couple your two extensions together. Extensions can access every other extension via their ServiceContainer (self.container.extensions is the set of all of them) so you can reach into another extension and do what you like wit…

Basically, you can access the other extensions at the cost of coupling some of them. It is useful for de-coupling the code, but not their functional dependency on each other. This is how to do it:

```
class DependencyA(DependencyProvider):
    def setup(self):
        ...

    def get_dependency(self, worker_ctx):
        ...

class DepencyB(DependencyProvider):
    def setup(self):
        ...

    def start(self):
        # at this point all other extensions (entrypoints / dependencies) already went
        # through the 'setup' phase.

        # creates a map from attribute name (defined in the main service class) to the dependency
        # provider.
        dependency_providers = {dep.attr_name: dep for dep in self.container.dependencies}

        # get dependency by attribute name
        dependency_a = dependency_providers['dependency_a'].get_dependency(None)

        # get dependency by simple type checking
        results = list(filter(lambda d: isinstance(d, (DependencyA,)), dependency_providers.values()))
        if len(results) >= 1:
            dependency_a = results[0].get_dependency(None)

```

Definitely not simple, but helps to mitigate spaghetti code a little (when one dependency is doing too much).

---

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [February 10, 2019, 1:21pm UTC](https://discourse.nameko.io/t/dependencies-between-dependency-providers/397/3 "2019-02-10T13:21:02Z")

</div>

I got half-way through a reply to your original message and then got distracted, sorry. Looks like you’ve worked something out. For reference, here is what I was going to say:

* * *

The short answer is no, you can’t have one `DependencyProvider` depend on another. That’s because the _dependency injection_ step is specifically about injecting the result of `get_dependency` into a service worker. The injection mechanism only works from DP to service, not DP to DP.

A `DependencyProvider` can have nested `Extension`s or `SharedExtension`s though. A good example of this is the `HttpRequestHandler` (`@http`) entrypoint, which has a [`WebServer`](https://github.com/nameko/nameko/blob/master/nameko/web/handlers.py#L18) `SharedExtension`. In this arrangement there’s a single webserver listening on the port, handling requests for all the `@http` entrypoints.

I think I would use straight-up inheritance to solve your problem though. Is there a problem with using one `DependencyProvider` to establishes connections to Cassandra, and another that subclasses it to run the initialisation and provides the function to the service?

* * *

I don’t have enough information to comment on your particular use-case, but I generally discourage coupling extensions by name. It is often a sign of either overzealous code re-use, or poor separation of concerns.

By way of example, imagine a service that stores metrics and application data on the same physical database. It’s common to want to reuse the `DependencyProvider` from one for the other, whereas IMO it’d be better to use two explicitly separate extensions even if that involved some code duplication.

---

<div class="post-metadata">

**Author:** ![danielrs](https://avatars.discourse-cdn.com/v4/letter/d/3da27b/32.png) [@danielrs](https://discourse.nameko.io/u/danielrs)\
**Post date:** [February 11, 2019, 5:31pm UTC](https://discourse.nameko.io/t/dependencies-between-dependency-providers/397/4 "2019-02-11T17:31:44Z")

</div>

Hi @mattbennett,

Thanks for your response. I think you are right about trying to re-use code too much. I think the best approach is to inherit classes or just create a new extension (if code duplication is not that much).

Best regards.
