Search code examples
c#wpfdependency-injectioninversion-of-control

Implementing Dependency Injection with a singleton


I am using WPF with Entity Framework 6 (DB first), Caliburn.Micro, and MEF.

I am trying to implement IoC in my project. I am an absolute beginner in IoC, and unfortunately, I cant find too many examples where MEF is used with Repository Pattern.

So I have a few repositories, and I have created my Generic Unit of Work like this:

class GenericUoW : IUoW, IDisposable
{
    protected readonly DbContext _ctx;

    public GenericUoW(DbContext context)
    {
        _ctx = context;
    }

    public void Complete()
    {
        _ctx.SaveChanges();
    }

    public void Dispose()
    {
        _ctx.Dispose();
    }
}

My actual Unit of Work classes are implemented like this:

class InvoiceUoW : GenericUoW, IInvoiceUoW
{
    public InvoiceUoW(DbContext _ctx) : base(_ctx)
    {
        salesrepo = new SaleRepository(_ctx);
        itemsrepo = new ItemRepository(_ctx);
        materialrepo = new MaterialRepository(_ctx);
        raterepo = new RateRepository(_ctx);
        clientrepo = new ClientRepository(_ctx);
        taxrepo = new TaxRepository(_ctx);
        stockhistoryrepo = new StockHistoryRepository(_ctx);
        proformarepo = new ProformaRepository(_ctx);
    }

    public ISaleRepository salesrepo { get; private set; }
    public IItemRepository itemsrepo { get; private set; }
    public IMaterialRepository materialrepo { get; private set; }
    public IRateRepository raterepo { get; private set; }
    public IClientRepository clientrepo { get; private set; }
    public ITaxRepository taxrepo { get; private set; }
    public IStockHistoryRepository stockhistoryrepo { get; private set; }
    public IProformaRepository proformarepo { get; private set; }
}

Now, in my ViewModel, I am doing something like this:

[Export(typeof(InvoiceViewModel))]    
class InvoiceViewModel : PropertyChangedBase
{

    #region ctor
    [ImportingConstructor]
    public InvoiceViewModel(IInvoiceUoW invoiceUoW)
    {
        _uow = invoiceUoW;
        Clients = new BindableCollection<Client>(_uow.clientrepo.FetchAll());
    }

    #endregion

    private readonly IInvoiceUoW _uow;

    //other properties and methods
}

My question is related to the use of IoC/DI in InvoiceUoW. How do I implement constructor injection in that class? Because each of those repositories in that class has to be instantiated with the same DataContext. How do I make the DataContext a singleton? Please do note that I have several Unit of Work classes, each for one viewmodel.


Solution

  • Register the DbContext instance to be resolved and act like a singleton:

    var container = new CompositionContainer(); //Get it from where it belongs
    var dbContext = container.GetExportedValue<DbContext>();
    container.ComposeExportedValue<DbContext>(dbContext);
    

    For your UoW, MEF doesn't work the same way as Unity, in MEF you rather decorate the implementing type to tell the container it should register it:

    [Export(typeof(IUnitOfWork))]
    public class MyUnitOfWork : IUnitOfWork