編集:質問は最初にAutofacでタグ付けされました
Autofacを使用すると、必要なことを行うために辞書などを使用する必要はありません。カスタム パラメータを使用できます。
public class ConnectionStringParameter : Parameter
{
public override Boolean CanSupplyValue(ParameterInfo pi,
IComponentContext context,
out Func<Object> valueProvider)
{
valueProvider = null;
if (pi.ParameterType == typeof(String)
&& String.Equals(pi.Name, "connectionString",
StringComparison.OrdinalIgnoreCase))
{
valueProvider = () =>
{
// get connectionstring based on HttpContext.Current.Request.Url.Host
return String.Empty;
};
}
return valueProvider != null;
}
}
次に、モジュールを使用してパラメーターを登録します
public class ConnectionStringModule : Autofac.Module
{
protected override void AttachToComponentRegistration(
IComponentRegistry componentRegistry, IComponentRegistration registration)
{
registration.Preparing += registration_Preparing;
}
private void registration_Preparing(Object sender, PreparingEventArgs e)
{
Parameter[] parameters = new Parameter[] { new ConnectionStringParameter() };
e.Parameters = e.Parameters.Concat(parameters);
}
}
を使用してコンテナ内に登録する必要があるモジュール
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule(new ConnectionStringModule());
AutofacがconnectionStringString
という名前の型のパラメーターを解決する必要があるたびに、カスタム パラメーターが使用され、必要に応じて接続文字列が取得されます。
ちなみにこのコードサンプルはHttpContext.Current
. マルチスレッド プロセスの場合、null が返されることがあります。そのようなものに使用することはお勧めしませんHttpContext.Current
。インターフェイスなど、アクセスする代わりに中間クラスを使用できIConnectionstringProvider
ます。
public interface IConnectionstringProvider
{
String ConnectionString { get; }
}
public class ConnectionStringProvider : IConnectionstringProvider
{
public ConnectionStringProvider(Strong host)
{
// get connectionstring based on host
this._connectionString = String.Empty;
}
private readonly String _connectionString;
public String ConnectionString
{
get { return this._connectionString; }
}
}
パラメータ内でvalueProviderを変更する必要があります
valueProvider = () =>
{
return context.Resolve<IConnectionstringProvider>().ConnectionString;
};
IConnectionstringProvider
そして最後に、リクエストのlifetimescopeの最初にあなたを登録する必要があります:
class Program
{
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule(new ConnectionStringModule());
IContainer container = builder.Build();
container.ChildLifetimeScopeBeginning += container_ChildLifetimeScopeBeginning;
}
private static void container_ChildLifetimeScopeBeginning(
Object sender, LifetimeScopeBeginningEventArgs e)
{
String host = HttpContext.Current.Request.Url.Host;
ContainerBuilder childLifetimeScopeBuilder = new ContainerBuilder();
childLifetimeScopeBuilder.RegisterInstance(new ConnectionStringProvider(host))
.As<IConnectionstringProvider>()
.SingleInstance();
childLifetimeScopeBuilder.Update(e.LifetimeScope.ComponentRegistry);
}
}
もちろん、それを行う方法はたくさんありますが、あなたにはアイデアがあります