Autofac inject different services based on HTTP request

76 Views Asked by At

I've seen a lot a posts about implementing services with the same interface but I can't get a grasp on How to configure AutoFac to inject the service a want based on the Route called.

Let's say I have 4 services that all implement the same interface:

public interface IService { void DoSomething(); }
public class UpService: IService { public void DoSomething() { } }
public class DownService : IService { public void DoSomething() { } }
public class LeftService : IService { public void DoSomething() { } }
public class RightService : IService { public void DoSomething() { } }

What I'm trying to do is injecting only one of them based on the route called

[RoutePrefix("api/values")]
public class ValuesController : ApiController
{
  private readonly IService _service;

  public ValuesController(IService service)
  {
      _service = service;
  }

  [HttpPost]
  [Route("up")]
  public IHttpActionResult Up()
  {
    _service.DoSomething()
    return Ok();
  }
  [HttpPost]
  [Route("down")]
  public IHttpActionResult Down()
  {
    _service.DoSomething()
    return Ok();
  }
  [HttpPost]
  [Route("left")]
  public IHttpActionResult Left()
  {
    _service.DoSomething()
    return Ok();
  }
  [HttpPost]
  [Route("right")]
  public IHttpActionResult Right()
  {
    _service.DoSomething()
    return Ok();
  }

How should I register these 4 services? Should I use a filter maybe?

Thanks

2

There are 2 best solutions below

1
On

This is an FAQ in the Autofac documentation. Short version: If these are different things that need to be used in different places/contexts, they probably shouldn't be the same interface. The FAQ walks through why that's the case and examples of how to solve the issue.

0
On

So far this is How I've resolved this:

builder.RegisterType<UpService>().Keyed<IService>(Command.Up);
builder.RegisterType<DownService>().Keyed<IService>(Command.Down);
builder.RegisterType<LeftService>().Keyed<IService>(Command.Left);
builder.RegisterType<RightService>().Keyed<IService>(Command.Right);

And the controller


  public ValuesController(IIndex<Command, IService> services)
  {
      _services = services;
  }

  [HttpPost]
  [Route("up")]
  public IHttpActionResult Up()
  {
    _services[Command.Up].DoSomething()
    return Ok();
  }
  [HttpPost]
  [Route("down")]
  public IHttpActionResult Down()
  {
    _services[Command.Down].DoSomething()
    return Ok();
  }
  [HttpPost]
  [Route("left")]
  public IHttpActionResult Left()
  {
    _services[Command.Left].DoSomething()
    return Ok();
  }
  [HttpPost]
  [Route("right")]
  public IHttpActionResult Right()
  {
    _services[Command.Right].DoSomething()
    return Ok();
  }