views:

282

answers:

1

I am currently working on my first asp.net mvc application. I am trying to drink the kool-aid of all the the sample projects I see and trying to use the repository design pattern.

I have a interface called IUserRepository that looks like the following:

public interface IUserRepository
{
    IUser Add(IUser user);
    IQueryable<IUser> Fetch();
    IUser Update(IUser obj);
    void Delete(IUser obj);
}

My IUser interface has a bunch of properties and properties for CreatedBy, CreatedDate, ModifiedBy and ModifiedDate.

My UserRepository looks like the following:

public class UserRepository : IUserRepository
{
    private GimliDataContext db = null;

    public UserRepository()
    {
        db = new GimliDataContext();
    }

    public UserRepository(string connection)
    {
        db = new GimliDataContext(connection);
    }

    public IUser Add(IUser obj)
    {
        db.Users.InsertOnSubmit((User)obj);
        db.SubmitChanges();
        return obj;
    }

    public IQueryable<IUser> Fetch()
    {
        return db.Users.Select(b => b as IUser);
    }

    public IUser Update(IUser obj)
    {
        var user = db.Users.Where(u => u.UserId == obj.UserId).Single();
        user.Name = obj.Name;
        user.Password = obj.Password;
        user.Email = obj.Email;
        user.IsLocked = obj.IsLocked;
        user.IsDisabled = obj.IsDisabled;
        db.SubmitChanges();
        return user;
    }

    public void Delete(IUser obj)
    {
        var user = db.Users.Where(u => u.UserId == obj.UserId).Single();
        db.Users.DeleteOnSubmit(user);
        db.SubmitChanges();
    }
}

In my current web applications when my users login I stash my customer business principal on the current thread and when my business objects update I just user the Name property on the Identity property of the current business principal and it works great.

So what's my question? Should I just do the same thing within the Add or Update methods of my repository OR would it be better to actually pass in an IUser reference to the current User and just grab the UserId from there?

Appreciate any input!

+2  A: 

First I would suggest making your repository interface generic. Instead of your IUserRepository try this:

public interface IRepository<T>
{
    T Add(T entity);
    IQueryable<T> Fetch();
    T Update(T entity);
    void Delete(T entity);
}

That way you can use this interface for any of your domain models.

As far as your question is concerned (CreadedBy and ModifiedBy props), personally, that sounds like business logic and would be better suited inside of a Service class. But I would do it like you first said. Take the currently authenticated user's user id and just put it in there, instead of passing in another IUser to get the ID of. But if it was in a service you would then be able to mock up a different service for unit testing, with out the hassle of having to actually log into the system (having the mocked service supply a mock IUser).

I myself am a bit new to this so if there are any better suggestions I would also like to read about them.

David
Thanks David! What do you mean by a Service class? I am using a WCF Service to interface with the repository ... but not sure if that is what you are talking about.
mattruma
You're welcome. Think of the WCF service as your 'Presentation' tier, you would still want to have a separate service class that could be used by the WCF service as well as other non-WCF clients (fat clients, etc...). Look at Domain Driven Design that will fill you in on Services.
David