如何告诉Web API / Castle Windsor路由引擎在我的存储库中使用不同的数据库实例?

我使用模型,存储库和控制器的ASP.NET Web API Castle Windsorized应用程序了解事件流程:

0)客户端通过URI调用REST方法,例如:

http://localhost:28642/api/platypi/Count 

1)Castle Windsor的路由引擎映射拦截来电,发送实现接口platypiController的注册具体类在其构造函数中作为arg。

2)该构造函数确定要调用哪个方法(在这种情况下对应于“Count”)。

3)Controller方法调用Repository上的相应方法。

4)代码运行,数据收集和返回,用户认为这一切都很容易(一个极端观点)或神奇(另一个,稍微不那么极端,观点)。

我已经创建了一对利用它的项目,到目前为止它只是花花公子。 我们为不同的用户提供了几个数据库实例(特定客户端的DB1,另一个客户的DB2等)。这些表几乎但不完全相同(不保证保持不变),并且针对这些表的查询类似。

我的难题/挑战是如何或在何处拦截路由以这种方式或基于用户正在调用的“类”。

我想我需要N个存储库来实现每个接口,例如:

 interface FooBar class PhooBar : FooBar // targets DB#1 class PhooeyBar : FooBar // targets DB#2 class PoohBear : FooBar // targets DB#3 

但是,我如何告诉Castle Windsor或Web API我想要的具体类/存储库?

在任何给定时间,都会有来自需要为DB#1数据提供服务的客户端的Web API / Castle Windsor应用程序,需要DB#2数据的其他客户端以及需要DB#3数据的用户的请求。

这是在URI中完成的事情,例如:

 http://localhost:28642/api/platypi/Count/1 

(附加数字表示要使用的DB)

要么:

 http://localhost:28642/api/platypi/Count/PhooBar 

要么…???

在许多情况下,必须在一个Repository类和另一个Repository类之间进行更改的唯一事情是构造函数中的连接字符串。 具体来说,这个:

 @"Provider=Microsoft.ACE.OLEDB.12.0;User ID=qypav1;Password=QqPamPoamMSET;Data Source=C:\CatcherNTheRye\DATA\OMDDAT03.MDB;Jet OLEDB:System database=C:\Catch22\Data\trip.mdw")) 

……将需要:

 @"Provider=Microsoft.ACE.OLEDB.12.0;User ID=qypav1;Password=QqPamPoamMSET;Data Source=C:\CatcherNTheRye\DATA\OMDDAT01.MDB;Jet OLEDB:System database=C:\Catch22\Data\trip.mdw")) 

(OMDDAT03成为OMDDAT01)

您可以使用dependency injection将dbContext放入UnitOfWork:

 public interface IRepository where T : class { IQueryable GetAll(); void Add(T entity); void Delete(T entity); void DeleteAll(IEnumerable entity); void Update(T entity); bool Any(); } public class Repository : IRepository where T : class { private readonly IDbContext _context; private readonly IDbSet _dbset; public Repository(IDbContext context) { _context = context; _dbset = context.Set(); } public virtual IQueryable GetAll() { return _dbset; } public virtual void Add(T entity) { _dbset.Add(entity); } public virtual void Delete(T entity) { var entry = _context.Entry(entity); entry.State = EntityState.Deleted; _dbset.Remove(entity); } public virtual void DeleteAll(IEnumerable entity) { foreach (var ent in entity) { var entry = _context.Entry(ent); entry.State = EntityState.Deleted; _dbset.Remove(ent); } } public virtual void Update(T entity) { var entry = _context.Entry(entity); _dbset.Attach(entity); entry.State = EntityState.Modified; } public virtual bool Any() { return _dbset.Any(); } } 

最后:

 public interface IUnitOfWork : IDisposable { IRepository GetRepository() where TEntity : class; void Save(); } public class UnitOfWork : IUnitOfWork where TContext : IDbContext, new() { private readonly IDbContext _ctx; private readonly Dictionary _repositories; private bool _disposed; public UnitOfWork() { _ctx = new TContext(); _repositories = new Dictionary(); _disposed = false; } public IRepository GetRepository() where TEntity : class { if (_repositories.Keys.Contains(typeof(TEntity))) { return _repositories[typeof(TEntity)] as IRepository; } var repository = new Repository(_ctx); _repositories.Add(typeof(TEntity), repository); return repository; } public void Save() { _ctx.SaveChanges(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (this._disposed) return; if (disposing) { _ctx.Dispose(); } this._disposed = true; } } 

我只是复制并浏览我的一个项目中的代码,方法与在应用程序中使用多个dbcontext相同。

另请参阅此解决方案: N层应用程序中的多个DbContexts