Adam Jachocki
Adam Jachocki

Reputation: 2125

Retrieve existing IServiceScope

I have a solution with 30 projects. There are client projects: - WPF Client - Xamarin - WebApplication (MVC) - WebAPI.

Long description why do I need it: Now, I have some services that are the same for every client. One service (CommandFactory) needs to create a command (class of specific base type). These commands are first registered and then resolved when needed, for example:

public class ServiceThatUsesCommand
{
   ICommandFactory cmdFactory;

   public ServiceThatUsesCommand(ICommandFactory cmdFactory)
   {
      this.cmdFactory = cmdFactory;
   }

   public void DoSomething()
   {
      var cmd = cmdFactory.Resolve<SomeCommand>();
      cmd.Execute();
   }
}

As you can see I am able to avoid service locator and do some more thanks to ICommandFactory interface. For this to work I have to have my custom DI interface, because: (this is of course very simplified version of my CommandFactory)

public class CommandFactory: ICommandFactory
{
    IObjectFactory objFactory; //this is my DI container

    public CommandFactory(IObjectFactory objFactory)
    {
        this.objFactory = objFactory;
    }

    public T CreateCommand<T>() where T: IExecutableCommand
    {
        return objFactory.Resolve<T>();
    }
}

Short question But in WebApplication there is a little problem. I am not able to resolve valid objects. So this is because of my custom DI container. Or rather - container wrapper, look at this simplified implementation:

class WebIocContainer: IObjectFactory //this is a singleton
{
    IServiceProvider serviceProvider; //I set this in Startup

    //the only way I've found to get scoped service is:
    public T Resolve<T>()
    {
       using(var scope = serviceProvider.CreateScope())
       {
           return scope.ServiceProvider.GetRequiredService<T>();
       }
    }
}

Now, this is a real problem. Because whole web application depends on default DI container, but only my command factory needs IObjectFactory (which of course uses internally the default DI container).

And when I try to resolve an object, I create new scope and get new object instead of the one that already exists.

So the solution would be to get the existing scope and not create a new one. But how to do this?

Upvotes: 0

Views: 322

Answers (1)

Adam Jachocki
Adam Jachocki

Reputation: 2125

OK, I have found the answer. One has to use just HttpContext.RequestServices.GetService<>();

And then my IObjectFactory should and can be registered as scoped service.

Upvotes: 1

Related Questions