I’ve started down an Autofac rabbit hole that I think I need to pull myself out of. I have a .NET MVC site where a user can list their favorite players per sport (baseball, basketball, etc.) I have a Players controller, and I’m injecting IPlayerService
. However, my problem is that the service needs to know which sport we’re dealing with. I’m currently using keyed parameters with a Sports
enum which I’m registering in Autofac like so:
foreach (var value in Enum.GetValues(typeof(Sports)))
{
var sport = (Sports)value;
builder.RegisterType<PlayerService>()
.Keyed<IPlayerService>(sport)
.WithParameter(new NamedParameter("sport", sport))
.InstancePerLifetimeScope();
}
The sport also needs to get pushed down to IPlayerRepository
, which I have registered almost exactly the same as above with IPlayerService.
My ultimate question is, how do I register PlayersController
so it will properly inject IPlayersService
with the correct sport? Assume my route looks like www.example.com/players/baseball
.
This project is mainly to help me get more experience with Autofac, so it may be obvious I’m essentially a beginner with it.
2
Your composition root won’t have any idea what kind of sport to pass, since it is part of the overall initialization and not executed as part of any user request. Presumably, however, your controller will know what sport, perhaps by sniffing the querystring, or using other contextual data that is passed in as part of the routing logic.
If this is the case, then here is your solution:
- Don’t inject an
IPlayerService
. Instead, inject aIPlayerServiceFactory
. -
Modify the controller so that it will use the factory to get an
IPlayerService
of the appropriate type, e.g.class MyController : Controller { private readonly IPlayerServiceFactory _playerServiceFactory; public MyController(IPlayerServiceFactory psf) { _playerServiceFactory = psf; } public ActionResult MyAction(string sportType) { IPlayerService playerService = _playerServiceFactory.GetService(sportType); //Do other stuff return View(); } }