我在C#中遇到问题,当我想对数据库进行查询时,我创建了DBQuerier()
的新实例,并在其上调用Run()
方法。
DBQuerier
可以连接到多个数据库中的一个,具体取决于传递给run方法的内容 - 例如new DBQuerier().Run(DBEnum.CatDatabase)
;
DBQuerier
是图书馆的一部分,因为各种解决方案都使用它。
我有一个配置文件,我可以加载和解析以将所有连接加载到内存中,用于枚举查找。但是,我不确定如何保留这些信息。它看起来像是依赖注入的工作:
new DBQuerier(new MyConnectionStringLoader()).Run(...)
但是,我不希望它以每种方式加载文件并解析它以这种方式运行db查询。我无法将其存储在DBQuerier中,因为每次都会创建并丢弃此对象。
如果我创建一个ConnectionStringManager类,如果它是静态的,那么我就不能干净地依赖注入MyConnectionStringLoader,这会使单元测试变得更加困难。如果我把它作为单身人士,我会遇到类似的问题。
这个问题有一个很好的解决方案吗?谷歌搜索它已经发现无数帖子说“从不使用静态类或单例”#39;所以我很困惑。
答案 0 :(得分:2)
似乎DbQuerier
对任何数据库都完全相同。唯一改变的是连接字符串。
我会做这样的事情:
public interface IDbQuerier
{
void Run();
}
public abstract class BaseDbQuerier : IDbQuerier
{
private static IDictionary<DbEnum, string> _connections;
static BaseDbQuerier()
{
_connections = // Load connection strings from configuration
}
protected abstract DbEnum Database { get; }
public void Run()
{
string connectionString = _connections[Database];
// DbQuerier logic
}
}
public enum DbEnum
{
CatDatabase,
DogDatabase,
TurtleDatabase
}
然后是不同的实现:
public class CatDbQuerier : BaseDbQuerier
{
protected override DbEnum Database { get { return DbEnum.CatDatabase; } }
}
public class DogDbQuerier : BaseDbQuerier
{
protected override DbEnum Database { get { return DbEnum.DogDatabase; } }
}
public class TurtleDbQuerier : BaseDbQuerier
{
protected override DbEnum Database { get { return DbEnum.TurtleDatabase; } }
}
对每个数据库使用不同的实现将允许您使用您选择的DI框架轻松地将其注入任何需要它的类。
答案 1 :(得分:0)
在您的情况下,单身人士(支持DI)是一条有效的路线。