Skip to content

Make decorated classes directly referenceable #184

@adj123

Description

@adj123

Hi, I have possibly a slightly unusual case where I have some class which needs to be decorated twice, with the inner one registered as a hosted service:

public interface IMyExternalService { }
public class MyExternalServiceHttpApi : IMyExternalService { }
public class CachingLayerOverMyExternalService : IMyExternalService, IHostedService { }
public class SomethingElseDecoratingMyExternalService : IMyExternalService { }

services.AddSingleton<IMyExternalService, MyExternalServiceHttpApi>();
services.Decorate<IMyExternalService, CachingLayerOverMyExternalService>();
services.AddHostedService(sp => (CachingLayerOverMyExternalService)sp.GetRequiredService<IMyExternalService>()); // <-- Doesn't work
services.Decorate<IMyExternalService, SomethingElseDecoratingMyExternalService>();

The AddHostedService line doesn't work because by the time the function executes, IMyExternalService is already decorated with SomethingElseDecoratingMyExternalService. My only workaround at the moment is to publicly expose the underlying IMyExternalService in this decorator, but this is a hack - it's not part of the decorator's functionality, it's only there to facilitate the DI mechanism which happens to be used to compose all the classes.

I need some handle to be able to reference that inner decorator somehow for my AddHostedService call - eg. perhaps if Decorate also registered a transient service pointer to each decorated type, like if I could do:

services.Decorate<IMyExternalService, CachingLayerOverMyExternalService>();
services.AddHostedService(sp => sp.GetRequiredService<Decorator<CachingLayerOverMyExternalService>>().Value); // <-- Added automatically by the preceding .Decorate

I imagine the general problem here isn't limited to hosted services and this solution would help for cases when the decorator implements arbitrary multiple interfaces which it also needs to be registered against.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions