Need some help trying to solve a problem resolving an implementation of a service at runtime based on a parameter. In other words use a factory pattern with DI.
We have Autofac wired in to our MVC application. I am trying to figure out how we can use a user session variable (Call it Ordering Type) to be used for the Dependency Resolver to resolve the correct implementation of a service.
An example of what we are trying to do.
The application has two "types" of ordering - real eCommerce type of ordering (add stuff to a shopping cart, checkout etc).
The other is called Forecast ordering. Users create orders - but they do not get fulfilled right away. They go through an approval process and then fulfilled.
The bottom line is the data schema and back end systems the application talks to changes based on the order type.
What I want to do is:
I have IOrderManagerService
public interface IOrderManagerService { Order GetOrder(int orderNumber); int CreateOrder(Order order); }
Because we have two ordering "types" - I have two implementations of the the IOrderManagerService:
public class ShelfOrderManager : IOrderManagerService { public Order GetOrder(int orderMumber) { ...code } public int CreateOrder(Order order) { ...code } }
and
public class ForecastOrderManager: IOrderManagerService
{
public Order GetOrder(int orderMumber)
{
...code
}
public int CreateOrder(Order order)
{
...code
}
}
My First question is - in my MVC application - do I register these implementations as?
builder.RegisterType<ShelfOrderManager>().As<IOrderManagerService>(); builder.RegisterType<ForecastOrderManager>().As<IOrderManagerService>();
What we are planning on doing is sticking the user selected ordering type in a users session. When a user wants to view order status - depending on their selected ordering "type" - I need the resolver to give the controller the correct implementation.
public class OrderStatusController : Controller { private readonly IOrderManagerService _orderManagerService; public OrderStatusController(IOrderManagerService orderManagerService) { //This needs to be the correct implementation based on the users "type". _orderManagerService = orderManagerService; } public ActionResult GetOrder(int orderNumber) { var model = _orderManagerService.GetOrder(orderNumber); return View(model); } }
I've ready about the the delegate factory and this answer explains the concept well.
The problem is the runtime parameters are being used to construct the service and resolve at runtime. i.e.
var service = resolvedServiceClass.Factory("runtime parameter")
All this would do is give me "service" that used the "runtime parameter" in the constructor.
I've looked at Keyed or Named resolution too.
At first I thought I could combine these two techniques - but the controller has the dependency on the interface - not the concrete implementation. (as it should)
Any ideas on how to get around this would be MUCH appreciated.