Repository: reagento/dishka

Issue:
Incorrect behavior of @decorate in different components
Incorrect behavior of `@decorate` when working with the same element in different providers (different component for providers) 

The situation occurs that `@decorate` ignores component and also there is no possibility to specify for @decorate via Annotated which component to use explicitly, it is also impossible to explicitly specify component for the returned type.


Example code:

```python
import asyncio
from collections.abc import Iterable
from typing import Annotated

from dishka import Provider, Scope, provide, AsyncContainer, make_async_container, FromComponent, decorate


class SomeDatabase:
    def __init__(self, name: str):
        self._name = name

    def insert(self) -> str:
        return self._name


class MasterProvider(Provider):
    component = "Master"

    @provide(scope=Scope.APP, provides=SomeDatabase)
    def get_database_m(self) -> SomeDatabase:
        return SomeDatabase(name="Master")

    @decorate
    def decorate_service_m(self, database: SomeDatabase) -> Iterable[SomeDatabase]:
        print("before decorate SomeDatabase master")
        yield database
        print("after decorate SomeDatabase master")

class ReplicaProvider(Provider):
    component = "Replica"

    @provide(scope=Scope.APP, provides=SomeDatabase)
    def get_database_r(self) -> SomeDatabase:
        return SomeDatabase(name="Replica")

    @decorate
    def decorate_service_r(self, database: SomeDatabase) -> Iterable[SomeDatabase]:
        print("before decorate SomeDatabase replica")
        yield database
        print("after decorate SomeDatabase replica")

class ReaderInteractor:
    def __init__(self, storage: SomeDatabase):
        self.storage = storage

    def __call__(self):
        result = self.storage.insert()
        return f"some logic: {result}"


class WriterInteractor:
    def __init__(self, storage: SomeDatabase):
        self.storage = storage

    def __call__(self):
        result = self.storage.insert()
        return f"some logic: {result}"


class IoCProvider(Provider):
    @provide(scope=Scope.REQUEST)
    def foo_interactor_master(self, storage: Annotated[SomeDatabase, FromComponent("Master")]) -> WriterInteractor:
        return WriterInteractor(storage=storage)

    @provide(scope=Scope.REQUEST)
    def bar_interactor_replica(self, storage: Annotated[SomeDatabase, FromComponent("Replica")]) -> ReaderInteractor:
        return ReaderInteractor(storage=storage)

def create_providers() -> list[Provider]:
    return [MasterProvider(), ReplicaProvider(), IoCProvider()]


def create_di_container() -> AsyncContainer:
    return make_async_container(*create_providers())


async def main():
    container = create_di_container()
    async with container() as request_container:
        writer: WriterInteractor = await request_container.get(WriterInteractor)

        print(writer())

asyncio.run(main())
```

Output:
```
before decorate SomeDatabase master
some logic: Replica
```

Expected output:
```
before decorate SomeDatabase master
some logic: Master
```

Graph without decorate:
![Image](https://github.com/user-attachments/assets/cd10dbcd-fd2c-40aa-9c4b-9fbb49cb598b)

Graph with decorate:
![Image](https://github.com/user-attachments/assets/3717131e-93e9-4bf1-a93d-9d6a6ef56178)

Discussion:

Solution patch:
diff --git a/src/dishka/registry_builder.py b/src/dishka/registry_builder.py
index 27d802a..9a7f2ec 100644
--- a/src/dishka/registry_builder.py
+++ b/src/dishka/registry_builder.py
@@ -360,7 +360,8 @@ class RegistryBuilder:
         ):
             return
         depth = self.decorator_depth[provides]
-        decorated_component = f"{DECORATED_COMPONENT_PREFIX}{depth}"
+        decorated_component = (f"{DECORATED_COMPONENT_PREFIX}{depth}_"
+                               f"{provides.component}")
         self.decorator_depth[provides] += 1
         if old_factory is None:
             raise InvalidGraphError(  # noqa: TRY003


Test patch:
diff --git a/tests/unit/container/test_components.py b/tests/unit/container/test_components.py
index 25022d3..fee61a3 100644
--- a/tests/unit/container/test_components.py
+++ b/tests/unit/container/test_components.py
@@ -235,3 +235,38 @@ def test_result_component():
 
     container = make_container(ResultProvider().to_component("YYY"))
     assert container.get(float) == 42
+
+
+class Decorate2ComponentProviderX(Provider):
+    scope = Scope.APP
+    component = "X"
+
+    @provide
+    def foo(self) -> int:
+        return 42
+
+    @decorate
+    def bar(self, x: int) -> int:
+        return x + 1
+
+
+class Decorate2ComponentProviderY(Provider):
+    scope = Scope.APP
+    component = "Y"
+
+    @provide
+    def foo(self) -> int:
+        return -1
+
+    @decorate
+    def bar(self, x: int) -> int:
+        return x - 1
+
+
+def test_decorate_two_components():
+    container = make_container(
+        Decorate2ComponentProviderX(),
+        Decorate2ComponentProviderY(),
+    )
+    assert container.get(int, component="X") == 43
+    assert container.get(int, component="Y") == -2