Reputation: 2125
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
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