Search code examples
c#inversion-of-controlioc-containerautofac

Autofac runtime parameters


I'm new to autofac and looking to see the best practices on passing runtime values to constructor. I've read a bunch of stackoverflow questions where this is asked but none are fully fleshed out. Should we be using delegates, factory to create service etc. I know passing the container around is not the best way to accomplish this.

In my particular case I have a service that access multiple dependencies, say logging, dataprovider, etc. Along with the few services being passed I also have run-time parameters I need to capture, say userid, password. The userid and password are required for the SomeService and are looked up when a web viewer performs a particular action. Below is what I have and highlighted is the issue.

public class SomeService : ISomeService
{
    private readonly IDataProvider _dataProvider;
    private readonly ILog _log;
    private readonly string _username;  
    private readonly string _password;

    public SomeService(IDataProvider dataProvider, ILog log,
        string username, string password)
    {
      _dataProvider = dataProvider;
      _log = log;
      _username = username;
      _password = password;
    }
}

The dataprovider, and log are configured in autofac

builder.RegisterType<DataProviderService>().As<IDataProvider>()
builder.RegisterType<SomeLogService>().As<ILog>()

Most of the functionality of this "SomeService" requires a username and password to verify before performing tasks, so figured it best to pass into constructor when creating but have never dealt with run-time requirements for autofac. I've reviewed the question Autofac - resolving runtime parameters without having to pass container around and it seems close to what I need but need some more feedback on the best way to accomplish this.


Solution

  • In general you should prevent passing runtime values into constructors. That will complicate your design and your DI configuration a lot. Constructors are for dependencies and configuration values. Pass runtime values either through method arguments or inject a service that allows you to retrieve those runtime values. Take for instance an IUserContext service that allows retrieving the name current logged in user.