views:

128

answers:

3

I am finishing up a rewrite of a project management tool using ASP.NET MVC, LINQ2QL and the Repository design pattern. Pretty much following the NerdDinner example.

I have a class called Task that has a child list of TaskStages. For sake of this example the Stages are Ready, Under Development and Completed. I keep track of the current Stage on the Task, but everytime the Stage changes I want to write a historical record to the Task Stage table.

I'm struggling on where to put this functionality and maintain testability. Does it go in the Controller? Repository? or the partial class?

If this is a design issue, please let me know!

+2  A: 

You could handle this one of two ways.

Personally, I would create business objects that sat between the Controller and the Data Access (Repository/LINQ2SQL). You would then use those Objects as your Model and interact with the data through them.

You could also put the logic in the Controller...but then you have to repeat that logic across the board if there's more than one area of the application that needs to perform the same way.

Justin Niessner
I am really trying to keep the application thin, so if I didn't have to create a *real* business objects that would be the way I want to go. In order to test it correctly, I suppose I would have to put it in the Controller ... no?
mattruma
I'm wondering if I could just add an update() method to the repository, I could then do my checks there?
mattruma
The Repo really should not be for business logic - only data access. Put it in the controller if you must. Must like Justin i would suggest another layer of abstraction: domain objects and a Service layer. It's not a massive amount of work and you will reap the rewards immediately.
cottsak
This looks like the best way to handle it ... I was trying to stay away from this ... we use Csla for a lot of our other projects, and was really looking for something quick and dirty! Thanks for advice!
mattruma
A: 

I'm new to ASP.NET MVC but I would have a method on the class for changing stages and put the logic for tracking these changes within that method (refactoring as necessary). In short, I don't think this belongs explicitly in the controller.

Mayo
I was thinking the same ... but struggling with *how*. I would have to create an instance of the repository to do any data access I needed to do.
mattruma
+2  A: 

...everytime the Stage changes I want to write a historical record to the Task Stage table.

You need to have a service that is responsible for changing Stage:

public interface IStageChanger {
    void Rename(Task t, string newName);
    // etc
}

I'm struggling on where to put this functionality and maintain testability. Does it go in the Controller? Repository? or the partial class?

Neither. Service level. You can have another service responsible for writing the history, so the resulting implementation of IStageChanger would be similar to this:

public class StageChanger : IStageChanger {
 public StageChanger(ITaskHistoryWriter historyWriter) {
  // 
 }

 public void Rename(Task t,string newName) {
  history.Write(t, /*whatever*/)
 }
}

Then you using DependencyInjection container (Windsor or similar) just request your changer service.

Dmytrii Nagirniak