asp.net-mvc-3dependency-injectionrepository-patterncustom-membershipprovider

Need help in implementing Repository Pattern with Custom Membership ASP.NET MVC


I am implementing Repository Pattern in one of my project based on ASP.NET MVC4 and N-Tier Architecture. I am little confused as how to implement Custom Membership with Repository Pattern. Here are how I have implemented my classes so far.

//Generic Repository

public interface IRepository<T> where T : class
{
void Add(T entity);
void Delete(T entity);
void Update(T entity);
IQueryable<T> GetAll();
T FindBy(Expression<Func<T, bool>> expression);
IQueryable<T> FilterBy(Expression<Func<T, bool>> expression);
}

//Repository Base Class

public abstract class Repository<T> : IRepository<T> where T : class
{
private STNDataContext _stnDataContext;
private readonly IDbSet<T> _dbSet;

protected Repository(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
_dbSet = StnDataContext.Set<T>();
}

protected IDatabaseFactory DatabaseFactory { get; private set; }
public STNDataContext StnDataContext
{
get { return _stnDataContext ?? (_stnDataContext = new STNDataContext()); }
}
public void Add(T entity)
{
_dbSet.Add(entity);
_stnDataContext.Commit();
}

public void Delete(T entity)
{
_dbSet.Remove(entity);
}

public void Update(T entity)
{
_dbSet.Attach(entity);
_stnDataContext.Entry(entity).State = EntityState.Modified;
_stnDataContext.Commit();
}

public IQueryable<T> GetAll()
{
return _dbSet.ToList().AsQueryable();
}

public T FindBy(Expression<Func<T, bool>> expression)
{
return FilterBy(expression).SingleOrDefault();
}

public IQueryable<T> FilterBy(Expression<Func<T, bool>> expression)
{
return GetAll().Where(expression).AsQueryable();
}

//User Repository Interface

public interface IUserRepository : IRepository<User>
{
}

//User Repository

public class UserRepository : Repository<User>, IUserRepository
{
public UserRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
}

//Heres my Business Logic Layer

//Generic Service Interface

public interface IService<T>
{
void Add(T entity);
void Delete(T entity);
void Update(T entity);
IEnumerable<T> GetAll();
T FindBy(Expression<Func<T, bool>> expression);
IEnumerable<T> FilterBy(Expression<Func<T, bool>> expression);
}

//Service Base

public class Service<T> : IService<T> where T : class 
{
public void Add(T entity)
{
throw new NotImplementedException();
}

public void Delete(T entity)
{
throw new NotImplementedException();
}

public void Update(T entity)
{
throw new NotImplementedException();
}

public IEnumerable<T> GetAll()
{
throw new NotImplementedException();
}

public T FindBy(Expression<Func<T, bool>> expression)
{
throw new NotImplementedException();
}

public IEnumerable<T> FilterBy(Expression<Func<T, bool>> expression)
{
throw new NotImplementedException();
}
}

//User Service Interface

public interface IUserService : IService<User>
{
}

//User Service Implementation

public class UserService : Service<User>, IUserService
{
private readonly IUserRepository _userRepository;
private readonly IRoleRepository _roleRepository;

public UserService(IUserRepository userRepository, IRoleRepository roleRepository)
{
_userRepository = userRepository;
_roleRepository = roleRepository;
}

public IList<User> GetAllUsers()
{
return _userRepository.GetAll().ToList();
}

public User GetUser(int id)
{
return _userRepository.FindBy(x => x.UserId == id);
}

public User GetUser(string userName)
{
return _userRepository.FindBy(x => x.Username.Equals(userName));
}

public void CreatUser(User user)
{
_userRepository.Add(user);
}

public IList<User> GetUsersForRole(string roleName)
{
return _userRepository.FilterBy(x => x.Role.RoleName.Equals(roleName)).ToList<User>();
}

public IList<User> GetUsersForRole(int roleId)
{
return _userRepository.FilterBy(x => x.Role.RoleId == roleId).ToList<User>();
}

public IList<User> GetUsersForRole(Role role)
{
return GetUsersForRole(role.RoleId);
}

}

I am not very sure on Am I going the right way? If yes how do i implement my UserService class.

If no, what changes do i need to implement.

Any help on this is highly appreciable. Thanks in advance*strong text*


Solution

  • Your IService<T> looks an awfully lot like your IRepository<T> interface. That looks like a completely useless abstraction to me. Consumers can use the IRepository<T> abstraction directly. If your intension is to add features (such as cross-cutting concerns) to the IService<T> implementations; use decorators instead.

    Besides, why have an empty (non-generic) IUserRepository? There is no use over using the IRepository<User> directly. If your intention is to add extra methods to this IUserRepository later on, please don't. This interface, and the implementations of this interface, will start growing too big, get hard to maintain, and become hard to extend parts of your code base, because you will be violating the Single Responsibility Principle. Instead, give custom -user specific- operations their own classes (one class per operation), hidden by a generic interface, just as you already do with the IRepository<T>.

    The following two articles describe an attractive way of creating a more maintainable system by defining smaller focused classes that each encapsulate a single query or use case, which can be placed on top of your repository pattern:

    Last note. Your UserService class, looks a lot like the MembershipProvider class from the .NET framework. Why not use that class? There is a very interesting library that allows you to create a membership provider for MVC in a more structured, dependency-friendly way. You should definitely take a look.