我对my question here有一个很好的答案,但我不确定我是否可以将这个答案应用到我的项目中,因为我显然需要在我的控制器中使用这样的代码:
return DBConnectionStrings[DBSpecifier].Get(ID, CountToFetch);
...(其中DBConnectionStrings是一个字典)而不是:
return deptsRepository.Get(ID, CountToFetch);
真正的问题/挑战是我需要我的Repositorys的构造函数能够接受arg以便相应地更改DB连接字符串。那些构造函数可以使用前面文章中建议的词典,这样就不会像这样开始:
public DuckbillRepository()
{
using (var conn = new OleDbConnection(
@"Provider=Microsoft.Jet.OLEDB.4.0;User ID=NRBQ;Password=NRBQRotPS;Data
Source=C:\Platypus\DATA\PlatypusFlipper03.MDB;Jet OLEDB:System
database=C:\Platypus\Data\duckbill.mdw"))
{
......会是这样的:
public DuckbillRepository(string DBToUse)
{
using (var conn = new OleDbConnection(
string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;User
ID=NRBQ;Password=NRBQRotPS;Data Source=C:\Platypus\DATA\{0}.MDB;Jet
OLEDB:System database=C:\Platypus\Data\duckbill.mdw", DBToUse))
{
但是,我怎样才能从Controller中为Repository的构造函数指定一个arg(用于填充Repository方法然后查询的数据存储)?目前,典型的控制器如下所示:
static readonly IDuckbillRepository duckbillsRepository = new DuckbillRepository();
public IEnumerable<Duckbill> GetBatchOfDuckbillsByStartingID(int ID, int CountToFetch)
{
return duckbillsRepository.Get(ID, CountToFetch);
}
目前我能想到的最好的想法/最接近的是我需要这样的东西:
public IEnumerable<Duckbill> GetBatchOfDuckbillsByStartingID(string DBInstance, int ID, int CountToFetch)
{
IDuckbillRepository duckbillsRepository = new DuckbillRepository(DBInstance);
return duckbillsRepository.Get(ID, CountToFetch);
}
我是在正确的轨道上,还是在错误的树上狂奔?
答案 0 :(得分:2)
我想避免使用任何IoC,你有以下选择。
如果用户只能指定dbInstance
作为方法参数,那么只需要为DuckbillRepository
类型创建几个构造函数,并只调用适当的构造函数。
public IEnumerable<Duckbill> GetBatchOfDuckbillsByStartingID(
string dbInstance,
int id,
int countToFetch)
{
var duckbillsRepository = new DuckbillRepository(dbInstance);
return duckbillsRepository.Get(id, countToFetch);
}
如果可以在dbInstance
的构造函数中获取DuckbillItemsController
,那么我将实现duckbillRepository
字段并在构造函数中初始化它。
/// <summary>
/// Dependency Injection friendly controller.
/// </summary>
public class DuckbillItemsController : ControllerBase
{
public readonly DuckbillRepository duckbillRepository;
public IEnumerable<Duckbill> GetBatchOfDuckbillsByStartingID(
int id,
int countToFetch)
{
return duckbillRepository.Get(id, countToFetch);
}
/// <summary>
/// <see cref="HttpContext.Current"/> can be a source
/// of 'dbInstance' variable.
/// </summary>
public DuckbillItemsController()
: this(HttpContext.Current.Request["dbInstance"])
{
}
public DuckbillItemsController(string dbInstance)
: this(new DuckbillRepository(dbInstance))
{
}
public DuckbillItemsController(DuckbillRepository duckbillRepository)
{
this.duckbillRepository = duckbillRepository;
}
}
如果可以使用IoC,那么您可以在Passing Arguments IoC中了解Castle Windsor。
var repository =
container.Resolve<DuckbillRepository>(new Arguments(new { dbInstance }));
此方法对于可用的参数非常有用 组合根,就像你的Program.Main方法一样。虽然它可能看起来 一开始很简单,实际上经常被新人使用 温莎,它的适用性通常非常有限,另一方面 两种方式的使用频率更高。
答案 1 :(得分:0)
我已经制定了一项计划来完成这项工作,但我认为这很复杂,我正在寻找任何一种验证(“是的,这很丑陋,但这就是你所能做的一切”)或更好的想法。
在控制器中,更改此:
static readonly IDuckbillRepository deptsRepository = new DuckbillRepository();
......对此:
static readonly IDuckbillRepository deptsRepository = new DuckbillRepository(string siteVal);
在Repository中,从中更改构造函数:
public DuckbillRepository()
{
using (var conn = new OleDbConnection(
@"Provider=Microsoft.ACE.OLEDB.12.0;User ID=NRBQ;Password=NRBQ;Data Source=C:\PlatypusFin\DATA\PlatypusDAT03.MDB;Jet OLEDB:System database=C:\PlatypusFin\Data\nrotps.mdw"))
{
using (var cmd = conn.CreateCommand())
{
. . .
......对此:
public DuckbillRepository(string siteVal)
{
string connStr = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;User ID=NRBQ;Password=NRBQ;Data Source=C:\PlatypusFin\DATA\{0}.MDB;Jet OLEDB:System database=C:\PlatypusFin\Data\nrotps.mdw", siteVal);
using (var conn = new OleDbConnection(connStr))
{
using (var cmd = conn.CreateCommand())
{
. . .