如何告诉 Web API/Castle Windsor 路由引擎在我的存储库中使用不同的数据库实例? [英] How can I tell the Web API / Castle Windsor routing engine to use a different database instance in my Repository?

查看:28
本文介绍了如何告诉 Web API/Castle Windsor 路由引擎在我的存储库中使用不同的数据库实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My understanding of the flow of events with an ASP.NET Web API Castle Windsorized app that uses Models, Repositories, and Controllers:

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

0) The client calls a REST method via a URI such as:

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

1) Castle Windsor 的路由引擎映射拦截该传入调用,发送实现接口 platypiController 的注册具体类,作为其构造函数中的 arg.

1) Castle Windsor's routing engine maps intercepts that incoming call, sending the registered concrete class that implements the interface platypiController has as an arg in its constructor.

2) 该构造函数确定要调用其哪个方法(在本例中对应于Count").

2) That constructor determines which of its methods is to be called (what corresponds to "Count" in this case).

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

3) That Controller method calls a corresponding method on the Repository.

4) 运行代码,收集并返回数据,用户认为这一切都那么简单(一个极端的观点)或神奇(另一个稍微不那么极端的观点).

4) The code is run, the data gathered and returned, and the user thinks it's all so easy (one extreme viewpoint) or magical (another, slightly less extreme, viewpoint).

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

I've created a pair of projects that utilize this and it so far works just dandy. We have several instances of databases for different users (DB1 for a particular set of customers, DB2 for another, etc.) The tables are almost but not quite identical (not guaranteed to remain such), and the queries against those tables are similar.

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

My conundrum/challenge is how or where to intercept the routing to go this way or that based on which "class" of user is calling.

我在想我需要 N 个 Repositories 来实现每个接口,例如:

I'm thinking that I need N Repositories implementing each interface, such as:

interface FooBar

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

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

But then, how do I tell Castle Windsor or Web API which concrete class/Repository I want?

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

At any given time, there will be requests coming into the Web API / Castle Windsor app from clients who need to be served DB#1 data, other clients who need DB#2 data, and yet users who need DB#3 data.

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

Is this something that's accomplished in the URI, such as:

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

(其中附加的数字表示要使用的数据库)

(where the appended number indicates which DB to use)

?

或:

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

或者……???

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

In many cases, the ONLY thing that will have to change between one Repository class and another is the connection string in the constructor. Specifically, this:

@"Provider=Microsoft.ACE.OLEDB.12.0;User ID=qypav1;Password=QqPamPoamMSET;Data Source=C:CatcherNTheRyeDATAOMDDAT03.MDB;Jet OLEDB:System database=C:Catch22Data	rip.mdw"))

...需要是:

@"Provider=Microsoft.ACE.OLEDB.12.0;User ID=qypav1;Password=QqPamPoamMSET;Data Source=C:CatcherNTheRyeDATAOMDDAT01.MDB;Jet OLEDB:System database=C:Catch22Data	rip.mdw"))

(OMDDAT03 变成 OMDDAT01)

(OMDDAT03 becomes OMDDAT01)

推荐答案

你可以使用依赖注入将你的 dbContext 放入 UnitOfWork :

you can use dependency injection to place your dbContext into UnitOfWork :

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();

    void Add(T entity);

    void Delete(T entity);

    void DeleteAll(IEnumerable<T> entity);

    void Update(T entity);

    bool Any();
}

public class Repository<T> : IRepository<T> where T : class
{
    private readonly IDbContext _context;
    private readonly IDbSet<T> _dbset;

    public Repository(IDbContext context)
    {
        _context = context;
        _dbset = context.Set<T>();
    }

    public virtual IQueryable<T> 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<T> 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<TEntity> GetRepository<TEntity>() where TEntity : class;

    void Save();
}

public class UnitOfWork<TContext> : IUnitOfWork where TContext : IDbContext, new()
{
    private readonly IDbContext _ctx;
    private readonly Dictionary<Type, object> _repositories;
    private bool _disposed;

    public UnitOfWork()
    {
        _ctx = new TContext();
        _repositories = new Dictionary<Type, object>();
        _disposed = false;
    }

    public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
    {
        if (_repositories.Keys.Contains(typeof(TEntity)))
        {
            return _repositories[typeof(TEntity)] as IRepository<TEntity>;
        }
        var repository = new Repository<TEntity>(_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.

I just copy and past the code from one of my projects, by using the same way you can have several dbcontext in your application.

也看看这个解决方案:N 层应用程序中的多个 DbContext

这篇关于如何告诉 Web API/Castle Windsor 路由引擎在我的存储库中使用不同的数据库实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆