-4

I'm developing a multi-database application. There is one admin database and many customer databases which are identical in structure.

I also have a generic RepositoryBase which looks like the following:

public abstract class RepositoryBase<T> where T : IEntityModel
{
    public IDbConnection DbConnection { get; set; }

    /* ... further properties ... */

    protected RepositoryBase(IDbConnection dbConnection)
    {
        DbConnection = dbConnection;
    }

    public async Task Insert(T entity)
    {
        await DbConnection.InsertAsync(entity);
    }

    public async Task<T> Get(int id)
    {
        var entityKey = CreateEntityKey(id);

        return await DbConnection.GetAsync(entityKey);
    }

    /* ... UPDATE, DELETE etc. ... */
}

At certain points in the software I'm using this class for inserting both to the Admin DB and the customer DBs.

Now, I need advice on how should I change the database names when I'm using one of these base repository methods? (note: in every request I'm getting the database name from the Admin DB based on the logged in user and injecting it into the DI)

My possibilities:

  • add database name as a parameter in these methods
  • where used (e.g. in a service) change the database of the current repository instance
  • get rid of these base methods and implement them individually
  • other?

Which approach is the best do you think? Thank you!

  • 1
    Sharing your research helps everyone. Tell us what you've tried and why it didn't meet your needs. This demonstrates that you've taken the time to try to help yourself, it saves us from reiterating obvious answers, and most of all it helps you get a more specific and relevant answer. Also see How to Ask – gnat Oct 8 at 14:09
  • I don't need education on how to ask a question on this site. The reason why I didn't ask this question on stackoverflow is because it's an opinion question including best practices. I thought this is the site for that. Or? – Mitulát báti Oct 8 at 14:13
  • 2
    Questions asking for opinions are explicitly off-topic on pretty much every single site in the Stack Exchange network. Questions asking for best practices are opinion-based unless they provide an objectively quantifiable, precise, unambiguous definition of how to measure whether a practice is "best". – Jörg W Mittag Oct 8 at 16:06
  • Ok, I'm sorry that it wasn't another how to get date in java question, but I needed help in this. What should I have done differently? – Mitulát báti Oct 8 at 18:19
  • 1
    There is nothing you can do differently. You said yourself in your comment: "it's an opinion question". Opinion questions are off-topic, and if it is opinions you are after, then there is nothing you can do to make in on-topic, other than making it not about opinions. – Jörg W Mittag Oct 8 at 20:08
1

Rather than injecting your repository as a shared thing, you might consider creating a repository factory that accounts for the context of the currently logged in user, selects the right connection, instantiates the repository and then returns it.

public class RepositoryFactory<T> where T: EntityModel 
{
    public Dictionary<String, IDBConnection> tenants { get; set; }

    public RepositoryBase<T> CreateRepository(string tenantId) 
    {
        return new Repository<T>(tenants[tenantId]);
    }
}

Of course, you could get a lot more sophisticated with how you determine which one to return (your lookup to the top-level database could happen here) and this code isn't fleshed out, but the idea is there. In your service layer code you would have something like:

public class MyBusinessLogic 
{
    public RepositoryFactory<MyThing> Factory { get; set; } // let DI inject this

    public void DoSomethingImportant()
    {
        Factory.CreateRepository(myTenantId).Insert(mything);
    }
}
| improve this answer | |
  • I think this is what I was looking for. Thank you Michael. – Mitulát báti Oct 8 at 14:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.