ラムダを受け取るRegister
のオーバーロードはジェネリックをサポートしていません。この理由は、Simple Injectorがオブジェクトグラフをあなたのためにもう分析できず、あなたのために分析を行うことができないためです。
あり、複数のソリューションがありますが、最も単純には、データオブジェクトに接続文字列パラメータを抽出し、リポジトリはその依存させることですおそらくです:
public class ConnectionStringSettings
{
public readonly string ConnectionString;
public ConnectionStringSettings(string connectionString) {
this.ConnectionString = connectionString;
}
}
container.RegisterSingleton(new ConnectionStringSettings("constr"));
container.Register(typeof(IRepository<>), typeof(Repository<>));
別のオプションは、接続文字列を登録することです条件付き登録を直接使用する:
container.RegisterConditional(typeof(string),
Lifestyle.Singleton.CreateRegistration(typeof(string),
() => "constr", container),
c => c.Consumer.ImplementationType.Name == typeof(Repository<>).Name);
このようにして、コンストラクタ引数をそのまま使用できます。欠点は、この登録はやや複雑であり、この条件付き登録は文字列のような参照型でのみ機能するということです。我々はfixこれをv4で行うかもしれない。
別のオプションは、明示的にすべての実装を登録することである。
container.Register<IRepository<User>>(() => new Repository<User>("connString"));
container.Register<IRepository<Order>>(() => new Repository<Order>("connString"));
container.Register<IRepository<Asset>>(() => new Repository<Asset>("connString"));
別のオプションは、未登録のタイプの解像度を使用することです:
container.ResolveUnregisteredType += (s, e) =>
{
Type serviceType = e.UnregisteredServiceType;
if (serviceType.IsGenericType &&
serviceType.GetGenericTypeDefinition() == typeof(IRepository<>))
{
Type implementationType = typeof(Repository<>)
.MakeGenericType(serviceType.GetGenericArguments()[0]);
Registration r = Lifestyle.Transient.CreateRegistration(
serviceType,
() => Activator.CreateInstance(implementationType, "connectionString"),
container);
e.Register(r);
}
};
は、さらに別のオプションはoverride Simple Injector's default behavior when it comes to parameter injectionにあるが、これは非常に多くを要求しますこれは私が通常アドバイスするものではありません。