Question

Having a repository pattern, in the controller one can do:

public class ProductController : Controller {
    private IUow Uow;

    public ProductController(IUow uow) {
        Uow = uow;
    }


    [HttpGet]
    public ActionResult Edit(int id) {
        ViewData.Model = Uow.Products.Get(id);
        return View();
    }

    [HttpPost]
    public RedirectToRouteResult Edit(int id, ProductEditBindingModel model) {
        if (ModelState.IsValid) {
            Uow.Products.Update(id, model);
        }
        return RedirectToAction("Edit");
    }
}

Example simplified

That is ok, but what happen when your business logic is a little bit complex? let's say using various methods from Unit of Work or other logic.

For example, let's say we need to : Audit the edit, update an underlying index, add scores to user for updating the product, publish the update into the users 'wall', whatever you can imagine.

It doesn't feels right (and I'm sure it's not) to populate the controller with lots of code, so I feel natural to just use a Business Model like :

[HttpPost]
public RedirectToRouteResult Edit(int id, ProductEditBindingModel model) {
    if (ModelState.IsValid) {
        Model.UpdateProduct(id, model);
    }
    return RedirectToAction("Edit");
}

The model, would need to access to the Uow so I think the Model should looks like something like :

public class ProductModel {
    private IUow Uow;

    public ProductModel(IUow uow) {
        Uow = uow;
    }
    public void UpdateProduct(int id, ProductEditBindingModel model) {
        // all logic with access to the Unit of Work.
    }
}

and the product controller like :

public class ProductController : Controller {
    private IUow Uow;
    private ProductModel Model;
    ProductController(IUow uow) {
        Uow = uow;
        ProductModel = new ProductModel(uow);
    }
    ....
}

Is this ok? One thing is that ProductController now depends on ProductModel, so I think it would be wise to create an Interface (IProductModel) and inject the dependency, but that means the constructor of ProductController will need to receive IUow and IProductModel. What happens when you need to access more than one Model? Creating exactly one model for that controller alerts me of duplicating code. Using multiple models on Controller dependecy 'looks fine' but something make me feel there's a key concept or 'thing' I'm missing.

Another things that I'm wondering is, if we like to stick to a pattern, in a simple get scenario, I can do Uow.Products.Get(id) but sometimes I will be accessing the Uow directly and others the Model. Would be wise to always access the Model like ProductModel.Get(id) instead ? I don't like to decide whenever I need to access model and when I need to just use the repository. looks like a bad strategy that doesn't scale up very well.

Another option that comes into my mind is using the Repository as a Model, but I quickly discarded because the ProductRepository does not know about the UserRepository so logic that must interact with both doesn't fit.

I also don't like the idea of a ProductModel accessing the UserRepository, that set me back to the controller doing all the 'hard' work which I know it's bad.

I hope you understand my situation, I tried to describe the best I can. The question is : How should I manage complex action in a Uow / Repository Pattern in MVC, and where the proper place of the BusinessLogic Model, who is responsible for the call to, and how complex action that access more than one repository are managed, accessed, etc.

Was it helpful?

Solution

I think your approach is almost ok. The name ProductModel suggests that it's a model, and therefore it should not contain any business logic. You need to create a ProductRepository to handle the business logic for the ProductModel.

Take a look at this article. Here the class Student is the model, and StudentRepository handles the business logic.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top