HiveBrain v1.2.0
Get Started
← Back to all entries
principlecsharpMinor

Unit of Work and Repository Design Pattern Implementation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
designrepositoryworkandimplementationpatternunit

Problem

User and Role are just examples; also, code is sparse on purpose (i.e. for demonstration purposes only).

Thoughts? (e.g. good, bad, etc.)

Interfaces

public interface IEntity
{
    int Id { get; }
}

public interface IUser
    : IEntity
{
    string Username { get; }
    string Email { get; }
    ICollection Roles { get; }
}

public interface IRole
    : IEntity
{
    string Name { get; }
    ICollection Users { get; }
}

public interface IContext
    : IDisposable
    where TEntity : class, IEntity
{
    IDbSet Entities();
    int SaveChanges();
}

public interface IUserContext
    : IContext
    where TUser : class, IUser
{
}

public interface IRoleContext
    : IContext
    where TRole : class, IRole
{
}

public interface IRepository
    : IDisposable
    where TEntity : class, IEntity
{
    TEntity Find(int id);
    IEnumerable Find(Expression> filter);
    void Add(TEntity entity);
    void Remove(TEntity entity);
}

public interface IUserRepository
    : IRepository
    where TUser : class, IUser
{
}

public interface IRoleRepository
    : IRepository
    where TRole : class, IRole
{
}

public interface IUnitOfWork
    : IDisposable
    where TUser : class, IUser
    where TRole : class, IRole
{
    IUserRepository Users();
    IRoleRepository Roles();
    int SaveChanges();
}


Classes

```
public abstract class Entity
: IEntity
{
public virtual int Id { get; set; }
}

public class User
: Entity, IUser
{
private ICollection _roles;

public string Username { get; set; }
public string Email { get; set; }

public virtual ICollection Roles
{
get { return _roles ?? (_roles = new Collection()); }
set { _roles = value; }
}
}

public class Role
: Entity, IRole
{
private ICollection _users;

public string Name { get; set; }

public virtual ICollection Users
{
get { return _users ?? (_users = new Collection()); }
set { _users = value; }
}
}

public abstract class Co

Solution

You should not dispose the context in the Repository's dispose method, because it has been injected via the constructor and you have no information if you can safely dispose it or not. If the same context has been passed into another repository then you would break it by disposing it.

Please read this for a full explanation and an example how to do it the correct way: https://dusted.codes/dont-dispose-externally-created-dependencies

In short you can re-factor the code to use a factory, so that you are in charge of creating and disposing a context object.

Context

StackExchange Code Review Q#31822, answer score: 2

Revisions (0)

No revisions yet.