2

I have a legacy asp.net web application which has 2 layers , UI and BusinessLayer. The UI project is of type ASP.NET website and BL is of type class library. The BL project has classes for entities of my app like Customer,User,Empoloyee etc.. Each class has methods for Reading from Database and Populate the object properties from the DataReader.that means the Customer Class contains my Customer object and Data Access Methods together.

Now I changed the web app to support MVC too. The old site (webforms) works as it used to be and the new upgrade to the site i am making (adding admin features to manage the site) is in ASP.NET MVC3. The routing and everything works fine. But i am worried about the structure /maintainability of the project.

For the new MVC part, I had to create ViewModels for few of the Entities like CustomerViewModel,EmployeeViewModel. I created another class called "CustomerService" With methods like GetCustomerViewModel and inside that method i call the GetCustomerMethod from the Existing BusinessLayer and read property values from the object ( of entity type mentioned in the existing BL project) and assign that to the CustomerViewModel (I will look into some AutoMapper samples for this later)object and return that from this method. My View will use this object to show data in the UI. The reason i created the "CustomerService" class is i may need to do some if condition checking or some business validations before setting the values to CustomerViewModel object. I consider that as a "Middle Layer / Service layer" so that my Controllers will be thin.

From my Customer Controller

public ActionResult Details(int id)
{

   MyProject.MVCViewModel.CustomerViewModel objCustomerVM;
   objCustomerVM=MyProject.MVCMiddleLayer.CustomerService.GetCustomerViewModel(id);

   return View(objCustomerVM); 
}

In my CustomerViewModel

 public static CustomerViewModel GetCustomerViewModel(int customerId)
    {
       //Create an object of new ViewModel
       CustomerViewModel objCustomerViewModel  = new CustomerViewModel ();

       //Get an object from Existing BL of Customer of type ExistingBL.Customer
       ExistingBL.Customer objCustOld=new Customer(customerId); 

        //Check some properties of the customer object and set values to the new ViewModel object
          if(objCustOld.Type=="normal")
          {
            objCustomerViewModel.Priority=2; 
          }
          else if(objCustOld.Type=="abnormal")
          {
            objCustomerViewModel.Priority=1;
            objCustomerViewModel.Message ="We love you";
          }
         //Some other checking like this....
    return objCustomerViewModel;
   }

Is this a wrong approach ? Is my code going to be messy ? I am not happy about the ViewModel since it is (almost) the duplicate code from my Existing BL entities. What is the best way to address this scenario. I am not sure about using Repository Pattern (which i saw in most of the examples) in this case ? Should i do that ?How is it going to improve my code ?

Happy
  • 1,767
  • 6
  • 22
  • 26
  • Don't like always just pasting links, but here's some good info that may help, http://stackoverflow.com/questions/5306655/using-view-models-in-asp-net-mvc-3 – Luke Hutton Dec 22 '11 at 19:39

2 Answers2

0

The approach that I would take would be similar to repository pattern. I would outline few key points

  1. Since the only thing that you would be rewriting would be UI logic (View Model Object), and its fine as your UI technologies are different(asp.net vs MVC)

  2. I would suggest you start working on interfaces so that later on you could do a dependency injection. The biggest benefit I generally with dependecy injection in mvc is while writing NUnit test cases.

public static ICustomerViewModel GetCustomerViewModel(int customerId) { //use DI, rather than concerete implementation ICustomerViewModel objCustomerViewModel = new CustomerViewModel ();

   //use DI, rather than concerete implementation
   ExistingBL.ICustomer objCustOld=new Customer(customerId); 
   .
   .
   .
return objCustomerViewModel;

}

You could now very easily create mock objects with the help of any mocking frame work.

Anand
  • 14,545
  • 8
  • 32
  • 44
0

More or less my ViewModel classes are a redefinition of properties with only attributes, someone may argue that this is just another overhead layer, but I do this for a simple reason: I can add proper Web Validation's attributes without breaking anything (The DataLayer shoudl be shareable with other apps).

In shorts given a DataLayer class exposing a User object:

public class DalUser {
  public int Id { get; set;}
  public int Age { get; set;}
  public string Name { get; set;}
  public string Surname { get; set;}

  // Business method for reading/writing/deleting

}

My viewmodel is something like:

public class VmUser : DalUser 
{
   [Display(Name="ID Code")]
   public override int Id { get; set; }

   [Display(Name="Age")]
   [Required]
   public override int Age { get; set; }

}

This leads me to two goals: the former is I can use Attributes without worrying about breaking something else, the latter is I can hide from user some field, prevent field injection (e.g. from FireBug - but that's includes defining an Interface and using that, not plain subclassing).

That's proves pretty usefull within my corporate (we're doomed to use EntitySpaces) and it's one of the less ugly way I've found in order to partially reuse ES generated classes.

BigMike
  • 6,683
  • 1
  • 23
  • 24