AnonyMouse
AnonyMouse

Reputation: 18650

How to write a method to get a repository of a certain type from unit of work

Hi can anybody tell me how you could write a method to get a repository of a certain type from the unit of work?

So my unit of work is:

public class UnitOfWork : IUnitOfWork, IDisposable
    {
        private Context context = new Context();
        private VectorCheckRepository<Invoice> _invoiceRepository;
        private VectorCheckRepository<InvoiceLine> _invoiceLineRepository;

        public virtual Repository<Invoice> InvoiceRepository
        {
            get
            {
                if (this._invoiceRepository == null) {
                    this._invoiceRepository = new VectorCheckRepository<Invoice>(context);
                }
                return _invoiceRepository;
            }
        }

        public virtual VectorCheckRepository<InvoiceLine> InvoiceLineRepository
        {
            get
            {
                if (this._invoiceLineRepository == null) {
                    this._invoiceLineRepository = new VectorCheckRepository<InvoiceLine>(context);
                }
                return _invoiceLineRepository;
            }
        }

        public void Save()
        {
            context.SaveChanges();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed) {
                if (disposing) {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }

However at run time I want to get a repository from the unit of work based on a type.

So say I went:

_unitOfWork.GetRepository(invoice);

What I would be doing here is wanting to get back the InvoiceRepository because I passed it an invoice.

or:

_unitOfWork.GetRepository(invoiceLine);

I would want it to return the InvoiceLineRepository.

Does anyone know how to achieve this?

Upvotes: 0

Views: 353

Answers (2)

OdeToCode
OdeToCode

Reputation: 4986

Assuming your unit of work wraps an ObjectContext, you can use CreateObjectSet<T> , which gives you the data source for your repository to wrap.

For example:

public class SqlRepository<T> : IRepository<T>
                                 where T : class, IEntity {

    public SqlRepository(ObjectContext context) {
           _objectSet = context.CreateObjectSet<T>();
    }

    protected ObjectSet<T> _objectSet;
    // ....
}

You can see an example in this MVC3 project: http://dl.dropbox.com/u/13430676/employeetimecards.zip

The code accompanies an article on EF Testability using UoW and Repositories: http://msdn.microsoft.com/en-us/library/ff714955.aspx

Hope that helps,

Upvotes: 0

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364369

There is no generic way to do this (except some ugly slow reflection combined with naming conventions = no compile time check and easy to break solution). I did this by simply creating either method with a lot of ifs or by using prepared dictionary where I got either whole repository instance based on entity type or repository type for dynamic creation.

Upvotes: 1

Related Questions