I found two related posts that are close to my question but still not answer what I'm looking for.
Which design patterns can be applied to the configuration settings problem?
Should my program's "services" be responsible to get their own configuration?
I have an application using AutoFac as DI container and ran into the following problem. I have classes I register with AutoFac at startup, but some constructor parameters are only known during runtime. I made up a sample to show my intension. The comment shows the location in code where I want to retrieve an instance of a class and inject some configuration data at this point in time.
The idea behind it is to separate the implementation of a generic settings provider from the configuration of certain classes. The configuration should be retrieved from the settings provider (ISettingsProvider), be converted to a class related settings class (FooSettings) and then be injected at creation time into that class (Foo).
Any suggestions on how to do this?
My sample:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Autofac;
namespace FooNamespace
{
internal static class Program
{
private static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<SettingsProvider>().As<ISettingsProvider>().SingleInstance();
builder.RegisterType<AnotherService>().As<IAnotherService>().SingleInstance();
builder.RegisterType<Foo>();
builder.RegisterType<ClientClass>();
var container = builder.Build();
var myClient = container.Resolve<ClientClass>();
myClient.DoSomething();
}
}
public class Foo
{
private FooSettings _settings;
private IAnotherService _anotherService;
public Foo(IAnotherService anotherService, FooSettings settings)
{
_anotherService = anotherService;
_settings = settings;
}
}
public class FooSettings
{
public string SettingA { get; private set; }
public string SettingB { get; private set; }
public FooSettings(string settingA, string settingB)
{
SettingA = settingA;
SettingB = settingB;
}
}
public class ClientClass
{
private readonly ISettingsProvider _settingsProvider;
public ClientClass(ISettingsProvider settingsProvider)
{
_settingsProvider = settingsProvider;
}
public void DoSomething()
{
var providerSettings = _settingsProvider.GetSettings("fooSettings");
var fooSettings = new FooSettings(providerSettings[0], providerSettings[1]);
// what is the best way to get an instance of foo with the fooSettings set at runtime
// when Foo and IAnotherService have been registered with AutoFac
}
}
public interface ISettingsProvider
{
string[] GetSettings(string settingsGroup);
}
class SettingsProvider : ISettingsProvider
{
public string[] GetSettings(string settingsGroup)
{
return new string[2] {"valueA", "valueB"};
}
}
public interface IAnotherService
{
}
class AnotherService : IAnotherService
{
}
}