4

Is it possible to change the implementation of a interface for a specific scope? What I would like to have is a default implementation of a "ILogService" which will log data to disk. But for the task scheduler I use "IServiceScopeFactory.CreateScope()" to resolve the implementation of the tasks, but in this case I would like to use a different implementation for logging so the data will end up in my Database.

interface ILogService { void Write(string text); }

This has a default implementation

class LogDisk : ILogService { void Write(string text) { ... } }

But when I do a GetService() in a scope where class x is using ILogService I would like to use this

class LogTask : ILogService { void Write(string text) { ... } }

Is it possible to change the implementation of a interface for one specific scope?

Example

public class TaskFactory : ITaskFactory
{
    private IServiceScopeFactory _serviceScopeFactory;

    public TaskFactory(IServiceScopeFactory serviceScopeFactory)
    {
        this._serviceScopeFactory = serviceScopeFactory;
    }

    public ITaskDefinition GetDefinition(ETaskType taskType)
    {
        using (var scope = this._serviceScopeFactory.CreateScope())
        {
            var provider = scope.ServiceProvider.GetService<ITaskX>();
            return null;
        }
    }
}

Within the tasks, I don't want to look at how this should be implemented if I should use implementation A or B. Each task has its own dependencies, that is what I would like the dependency injection to take care of. But the only implementation I would like to change is the one for ILogService.

Josjr87
  • 193
  • 1
  • 13
  • A bit ugly I know, but you could create a second interface (that implements ILogService) and have two separate configurations in your dependency injection. – Cleptus Sep 20 '19 at 11:20
  • 2
    Possible duplicate of [How to register multiple implementations of the same interface in Asp.Net Core?](https://stackoverflow.com/questions/39174989/how-to-register-multiple-implementations-of-the-same-interface-in-asp-net-core) – IamK Sep 20 '19 at 11:24
  • @C1sc0 I don't want my task to know about version A or B, when I execute the task outside the scheduler it should just store the logging on disk. But when it is executed by the task scheduler, it should keep it in memory, so the scheduler can log it within the database. – Josjr87 Sep 20 '19 at 11:27
  • @bradbury9 I'm not suer what you mean. Because how can I then change the implementation for the scope of the task scheduler? – Josjr87 Sep 20 '19 at 11:28
  • I think what @C1sc0 linked is what you are looking for. – cl0ud Sep 20 '19 at 12:05
  • I now changed it so I have a "ILogService" which uses a "ILogProvider" to process the message. Within the service collection I changed it so I have one "ILogService" per scope. Within "ILogService" I added a overrideProvider function, so I can change the provider for a specific scope. That is what I replace in the beginning of the scope and all classes created during that scope will then contain the ILogService with a different implementation for provider. – Josjr87 Sep 20 '19 at 12:24
  • Thanks for your help guys, it works for now. I couldn't see the implementation working with the example link you sent me. Or at least it didn't feel better for my problem. – Josjr87 Sep 20 '19 at 12:24

0 Answers0