Unità di lavoro con più contesto di database

3

Ho creato un'applicazione (core core 2 & ef core) con pattern Unit Of Work e Generic repository. Avevo un solo contesto di database, ma a causa di alcune logiche di business ho dovuto creare un secondo database con alcune stesse entità.

Per semplicità, userò solo una Entity, la ProductEntity e userò solo 1 metodo repository the Get by Id .

Nella logica aziendale devo essere in grado di recuperare il Prodotto dai due contesti, fare alcune cose e quindi aggiornare i contesti, ma con un design UoW pulito.

Il repository è implementato in questo modo

public interface IRepository<TEntity>
    where TEntity : class, new()
{      
    TEntity Get(int id);     
}

public interface IProductsRepository : IRepository<ProductEntity>
{

}

public class ProductsRepository : Repository<ProductEntity>, IProductsRepository
{
    public ProductsRepository(DbContext context) : base(context)
    {

    }
}

Implementazione di UOW con un contesto db

public interface IUnitOfWork : IDisposable
{
    IProductsRepository ProductsRepository { get; }
    int Complete();
}

public class UnitOfWork : IUnitOfWork
{
    private readonly DbContext _context;

    public UnitOfWork(MainContext context)
    {
        // injecting the main database
        _context = context;
    }

    private IProductsRepository _productsRepository;
    public IProductsRepository ProductsRepository => _productsRepository ?? (_productsRepository = new ProductsRepository(_context));

    public int Complete()
    {
        return _context.SaveChanges();
    }

    public void Dispose()
    {
        _context?.Dispose();
    }
}

Sto usando il framework predefinito di .NET Core per DI, quindi nel mio file Startup.cs ho il seguente

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // ...

    // main database 
    services.AddDbContext<MainContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MainDatabaseConnection"), providerOptions => providerOptions.CommandTimeout(30)));

    // unit of work            
    services.AddTransient<IUnitOfWork, UnitOfWork>();
}

Per risolvere il problema ho creato un secondo UnitOfWork con contesto hardcoded e sto usando le stesse entità / repository

La mia implementazione con due contesti db

public interface IUnitOfWorkSecondary : IDisposable
{
    IProductsRepository ProductsRepository { get; }
    int Complete();
}

public class UnitOfWorkSecondary : IUnitOfWorkSecondary
{
    private readonly DbContext _context;

    public UnitOfWork(SecondaryDatabaseContext context)
    {
        // injecting the secondary database
        _context = context;
    }

    // same as above
}

Quindi in un oggetto aziendale sto facendo il seguente

public class Program
{
    private readonly IUnitOfWork _unitOfWork;
    private readonly IUnitOfWorkSecondary _unitOfWorkSecondary;

    public Program(IUnitOfWork unitOfWork, IUnitOfWorkSecondary unitOfWorkSecondary){
        _unitOfWork = unitOfWork;
        _unitOfWorkSecondary = unitOfWorkSecondary;
    }

    public static void Method1(int productId)
    {        
        var mainProduct = _unitOfWork.ProductsRepository.Get(productId);
        var secondaryProduct = _unitOfWorkSecondary.ProductsRepository.Get(productId);

        mainProduct.Name = "Hello Main";
        secondaryProduct.Name = "Hello Secondary";

        _unitOfWork.Complete();
        _unitOfWorkSecondary.Complete();
    }    
}

Il Startup.cs viene modificato in

// main database 
services.AddDbContext<MainContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MainDatabaseConnection"), providerOptions => providerOptions.CommandTimeout(30)));

// secondary database
services.AddDbContext<SecondaryContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SecondaryDatabaseConnectiont"), providerOptions => providerOptions.CommandTimeout(30)));

// unit of work            
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddTransient<IUnitOfWorkSecondary , UnitOfWorkSecondary>();

Le mie domande

  1. Qual è il design migliore (o più pratico) per questo
  2. Cosa succede se i database sono più di 2?
posta Dimitris 31.08.2018 - 09:11
fonte

0 risposte