编辑:这个问题最初是用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必须解析String
名为connectionString类型的参数时,它将使用自定义参数并根据您的需要获取您的连接字符串。
顺便说一下,这个代码示例使用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; }
}
}
在您的Parameter中,您必须通过以下方式更改valueProvider
valueProvider = () =>
{
return context.Resolve<IConnectionstringProvider>().ConnectionString;
};
最后,您必须IConnectionstringProvider
在请求生命周期的开头注册您的:
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);
}
}
当然有很多方法可以做到,但你有想法