Search code examples
c#inversion-of-controlautofac

Is using IoC container (such as autofac) to store application settings good practice?


Before I used to store settings such as connection strings on a settings.json file. Is creating classes like this bad practice?

Interface

public interface IConnectionString
{
    string Host { get; set; }
    string Password { get; set; }
    int Port { get; set; }
    string Username { get; set; }


    /// <summary>
    ///     Converts it to a string that DB will understand
    /// </summary>
    string AsString();
}

Classes

public class MongoDbLocalConnectionString : IConnectionString
{
    public int Port { get => 27017; set { } }

    public string Host { get => "localhost"; set { } }
    public string Password { get => null; set { } }
    public string Username { get => null; set { } }

    public string AsString()
    {
        if (string.IsNullOrEmpty(Host))
        {
            if (Debugger.IsAttached) { Debugger.Break(); }
            ULoggerDefinitions.Logger.Log(LogType.Error, "HBY5-BT7H", "host cannot be null");
            throw new Exception("98NO-KVKR");
        }

        // connect without authenticating
        if (string.IsNullOrEmpty(Password))
        {
            return $"mongodb://{Host}:{Port}";
        }

        // ... etc
    }
}

// Additional connection strings implementing IConnectionString....
public class DebugConnectionString : IConnectionString {
// ... etc

Now with autofac it is convenient to select what connection string I want to use. I can do things like:

var builder = new ContainerBuilder();

// register defaults
builder.RegisterType<CoreLogger>().As<ILogger>().SingleInstance();
builder.RegisterType<Foo>().As<IFoo>().SingleInstance();

using (var scope = builder.Build().BeginLifetimeScope((ContainerBuilder b) => {

    // register/override dependencies for this
    b.RegisterType<DebugConnectionString>.As<IConnectionString>();

    // can add more registrations...
}))
{
    // connection string will exist only in this scope
}

Having something like this instead of a settings.json file bad practice?


Solution

  • I think storing sensitive data in code is bad way. With IConfiguration you can use not only files but also environment variables (best way for deployment) or user secrets (best way if you don't want to store some protected data in git repository). Also you might want to use IOptions usage.

    Also, you need to re-build your project on any change (against re-run).