简体   繁体   中英

Repository Pattern, Unit of Work with Generics

I have the following code (I have ommited certain areas to make it simple)

public interface ICustomer
{

    int Age { get; set; }

    string Name { get; set; }
}

public class Customer : ICustomer
{

    public int Age { get; set; }


    public string Name { get; set; }
}

public interface ICustomerRepository<T> where T : class
{
    IEnumerable<T> GetCustomers();

    T GetCustomer();

    void AddCustomer(T customer);
}

public class CustomerRepository<T> : ICustomerRepository<T> where T:class 
{
    public IEnumerable<T> GetCustomers()
    {
        return new List<T>();
    }


    public T GetCustomer()
    {
        return null;
    }


    public void AddCustomer(T customer)
    {

    }
}


public class UnitOfWork //: IUnitOfWork
{

    public ICustomerRepository<ICustomer> CusRepo
    {
        get
        {
            return new CustomerRepository<Customer>();
            //Error: Error  1   Cannot implicitly convert   type 'ConsoleApplication1.CustomerRepository<ConsoleApplication1.Customer>' to 'ConsoleApplication1.ICustomerRepository<ConsoleApplication1.ICustomer>'. An explicit conversion exists (are you missing a cast?)    
        }

    }
}

I get the following error in the UnitOfWork class. How do I fix this?

.Error 1 Cannot implicitly convert type 'ConsoleApplication1.CustomerRepository' to 'ConsoleApplication1.ICustomerRepository'. An explicit conversion exists (are you missing a cast?)

I cannot use covariance since the parameter is used for both in and out purposes.

You should return repository as following:

get
{
    return new CustomerRepository<ICustomer>();
}

You cannot use variance here because your ICustomerRepository<T> have generic parameter in both in and out positions. To use variance, you can split ICustomerRepository<T> into two separate interfaces, like these:

interface IReadRepository<out T>
{
    IEnumerable<T> GetItems();
    T GetItem(int id);
}

interface IWriteRepository<in T>
{
    void AddItem(T item);
}

I have refactored the pattern in your sample code.

public class Customer
{
    public int Age { get; set; }
    public string Name { get; set; }
}

public interface IUnitOfWork
{
    int Save();
}

public interface IBaseRepository<TEntity, TKey> : IUnitOfWork where TEntity : class
{
    void Add(TEntity entity);
    TEntity Find(TKey id);
    IEnumerable<TEntity> GetAll();
}



public interface ICustomerRepository :IBaseRepository<Customer, int>
{

}

public class CustomerRepository : ICustomerRepository
{
    public void Add(Customer entity)
    {
        throw new System.NotImplementedException();
    }

    public Customer Find(int id)
    {
        throw new System.NotImplementedException();
    }

    public IEnumerable<Customer> GetAll()
    {
        throw new System.NotImplementedException();
    }

    public int Save()
    {
        throw new System.NotImplementedException();
    }
}


public class UnitOfWork : IUnitOfWork
{
    private ICustomerRepository _customers;

    public ICustomerRepository Customers
    {
        get { return _customers; }
    }

    public UnitOfWork()
    {
        _customers = new CustomerRepository();
    }

    public int Save()
    {
        throw new System.NotImplementedException();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM