6

I am using repository pattern on EF Core and Autofac in a windows service.

I have a service that needs to connect with the some dozen databases which have the same schema (same dbcontext) but only different data. How can I achieve this in my service using Autofac? Belo

public class ReportRepository : IReportRepository
    {
        private readonly ReportDbContext dbContext;

        public ReportRepository(ReportDbContext dbContext)
        {
            this.dbContext = dbContext
        }

        public SomeModel GetData()
        {
            return dbContext.SalesData;
        }
    }

    public class ReportService : IReportService 
    {
        private readonly IReportRepository reportRepositoryEUServer;

        public ReportService(IReportRepository reportRepositoryEUServer)
        {
            this.reportRepositoryEUServer = reportRepositoryEUServer
        }

        public SomeModelDto GenerateReport()
        {
            var euData =  reportRepositoryEUServer.GetData();
            // I need to call other servers (e.g LATAM) here and get the data and aggregate them with euData
        }       
    }
1

1 Answer 1

7

Create base context including all settings, dbsets etc:

public abstract class BaseContext : DbContext
{
    public BaseContext(DbContextOptions options)
    : base(options)
    { }
    public DbSet<object> FirstSet { get; set; }
    ...
}

inherit from BaseContext for both DBs

public class LATAMContext : BaseContext
{
    public LATAMContext(DbContextOptions<LATAMContext> options) : base(options)
    {

    }
}

public class EUContext : BaseContext
{
    public EUContext(DbContextOptions<EUContext> options) : base(options)
    {

    }
}

and register both in Startup.cs

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<LATAMContext>(options => options.UseSqlServer(Configuration.GetConnectionString("LATAMConnectionString")));
    services.AddDbContext<EUContext>(options => options.UseSqlServer(Configuration.GetConnectionString("EUConnectionString")));

    // Autofac
    var builder = new ContainerBuilder();

    // needed only if you plan to inject ICollection<BaseContext>
    builder.RegisterType<LATAMContext>().As<BaseContext>();
    builder.RegisterType<EUContext>().As<BaseContext>();

    builder.Populate(services);


    return new AutofacServiceProvider(builder.Build());
}

add connection strings in appsettings.json

"ConnectionStrings": {
  "LATAMConnectionString": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "EUConnectionString": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity1;Trusted_Connection=True;MultipleActiveResultSets=true"
}

and now you can inject both contexts

public class ReportRepository : IReportRepository
{
    private readonly LATAMContext latamDbContext;
    private readonly EUContext euDbContext;

    public ReportRepository(LATAMContext latamDbContext, EUContext euDbContext)
    {
        this.latamDbContext = latamDbContext;
        this.euDbContext = euDbContext;
    }
}

or if you plan to inject collection of contexts

public class ReportRepository : IReportRepository
{
    private readonly ICollection<BaseContext> dbContexts;

    public ReportRepository(ICollection<BaseContext> dbContexts)
    {
        this.dbContexts = dbContexts;
    }
}

to access specific context

var _euContext = dbContexts.FirstOrDefault(x => x is EUContext) as EUContext;
var _latamContext = dbContexts.FirstOrDefault(x => x is LATAMContext) as LATAMContext;
Sign up to request clarification or add additional context in comments.

4 Comments

Your solution seems ok but it is not what I want. I just gave a sample of two connections. I have dozens of these and hardcoding them is gonna be a mess. I will update the question as it was my mistake initially to not mention this.
check it: stackoverflow.com/questions/40836102/… should fit your needs
@Greg Does this work well with Code First Entity Framework DB Migrations?
@MbusoMkhize you can specify which context to use for migration --context MyDbContext

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.