Ok Dependency Ninja's,这是给你的......
我想根据我从内核请求的类型来改变Ninject构建依赖关系的方式。
我有一个带有以下构造函数的DbConnectionFactory类:
public DbConnectionFactory()
: this(MyDatabase.ConnectionString)
{
}
public DbConnectionFactory(string connectionString)
: this(DbProviderFactories.GetFactory("System.Data.SqlClient"), connectionString)
{
}
对于“默认”绑定,我希望Ninject使用无参数构造函数:
this.Bind<IDbConnectionFactory>().To<DbConnectionFactory>();
我的代码中的某些类需要Ninject来提供connectionString参数。我试图像这样设置绑定:
this.Bind<IDbConnectionFactory>().To<DbConnectionFactory>().Only(
When.Context.InstanceOf(typeof(IRepository))).WithArgument(
"connectionString", MyOtherDatabase.ConnectionString);
但是,我只让Ninject使用默认构造函数。
我一定错过了一些明显的东西!
答案 0 :(得分:3)
听起来好像这里的图层太多了。为什么需要DatabaseGateway?为什么不使用ADO.NET提供程序工厂来创建连接(您也可以通过Ninject连接它们)来直接管理连接?或者更好的是,使用存储库模式使用类似NHibernate的东西并使用它来映射对象?
无论如何,总是使用较长的构造函数并根据情况交替传入MyDatabase.ConnectionString或MyOtherDatabase.ConnectionString怎么样?您可以使用here和here所述的提供程序,但除非绝对必要,否则我会尽量避免使用它们:
定义两个新属性
public class DefaultDatabaseAttribute : Attribute {}
public class OtherDatabaseAttribute : Attribute {}
使用构造函数
中的相应属性装饰DatabaseGateway参数public class OneRepository : IRepository
{
public OneRepository([DefaultDatabase]DatabaseGateway factory)
{
}
}
public class TwoRepository : IRepository
{
public TwoRepository([OtherDatabase]DatabaseGateway factory)
{
}
}
并且您的提供商看起来像:
public class DatabaseGatewayProvider : SimpleProvider<DatabaseGateway>
{
protected override DatabaseGateway CreateInstance(Ninject.Core.Activation.IContext context)
{
IDbConnectionFactory factory;
if (context.Member.IsDefined(typeof(DefaultDatabaseAttribute), false))
{
factory = context.Kernel.get<IDbConnectionFactory>(With.Parameters.ConstructorArgument("connectionString", MyDatabase.ConnectionString)));
}
else if (context.Member.IsDefined(typeof(OtherDatabaseAttribute), false))
{
factory = context.Kernel.get<IDbConnectionFactory>(With.Parameters.ConstructorArgument("connectionString", MyOtherDatabase.ConnectionString)));
}
return new DatabaseGateway(factory);
}
}
您可以扩展此模型以添加其他属性,以确定是否需要在DatabaseGateway中返回工厂。
这很尴尬,但考虑到涉及的层数,可能是你能做的最好的。
答案 1 :(得分:1)
此article也可以帮助您。就像Jeff说的那样,你会想要使用With.Parameters.ConstructorArgument()。您可以通过继续链接ConstructorArgument或使用Dictionary来传递多个参数。希望这有帮助!