我有一个传统的asp.net Web应用程序,它有2层,UI和BusinessLayer。 UI项目是ASP.NET网站类型,BL是类型类库。 BL项目有我的应用程序实体的类,如Customer,User,Empoloyee等。每个类都有从数据库读取和从DataReader填充对象属性的方法。这意味着Customer Class包含我的Customer对象和数据访问方法
现在我改变了网络应用程序以支持MVC。旧网站(webforms)按原样运行,我正在进行的新网站升级(添加管理功能以管理网站)在ASP.NET MVC3中。路由和一切正常。但我担心项目的结构/可维护性。
对于新的MVC部分,我必须为少数实体(如CustomerViewModel,EmployeeViewModel)创建ViewModel。我创建了另一个名为“CustomerService
”的类,使用类似GetCustomerViewModel
的方法,在该方法中,我从Existing BusinessLayer调用GetCustomerMethod
,并从对象中读取属性值(在现有的BL项目)并将其分配给CustomerViewModel
(我将在稍后查看一些AutoMapper示例)对象并从此方法返回该对象。我的视图将使用此对象在UI中显示数据。我创建“CustomerService
”类的原因是我可能需要在将值设置为CustomerViewModel对象之前进行条件检查或某些业务验证。我认为这是一个“中间层/服务层”,以便我的控制器很薄。
来自我的客户控制器
public ActionResult Details(int id)
{
MyProject.MVCViewModel.CustomerViewModel objCustomerVM;
objCustomerVM=MyProject.MVCMiddleLayer.CustomerService.GetCustomerViewModel(id);
return View(objCustomerVM);
}
在我的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;
}
这是一种错误的做法吗?我的代码会变得混乱吗?我对ViewModel不满意,因为它(几乎)是来自我现有BL实体的重复代码。解决此问题的最佳方法是什么。在这种情况下,我不确定使用Repository Pattern(我在大多数示例中看到过)?我应该这样做吗?如何改进我的代码?
答案 0 :(得分:0)
我将采用的方法类似于存储库模式。我将概述几个关键点
因为你要改写的唯一东西就是UI逻辑(View Model Object),而你的UI技术则不同(asp.net vs MVC)
我建议你开始使用接口,以便以后可以进行依赖注入。我通常在mvc中使用dependecy注入的最大好处是在编写NUnit测试用例时。
public static ICustomerViewModel GetCustomerViewModel(int customerId) { //使用DI,而不是概念实现 ICustomerViewModel objCustomerViewModel = new CustomerViewModel();
//use DI, rather than concerete implementation
ExistingBL.ICustomer objCustOld=new Customer(customerId);
.
.
.
return objCustomerViewModel;
}
现在,您可以借助任何模拟框架工作轻松创建模拟对象。
答案 1 :(得分:0)
或多或少我的ViewModel类是仅具有属性的属性的重新定义,有人可能会认为这只是另一个开销层,但我这样做的原因很简单:我可以添加适当的Web Validation属性而不会破坏任何内容(The DataLayer可以与其他应用共享。)
简而言之,给出了一个公开User对象的DataLayer类:
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
}
我的viewmodel类似于:
public class VmUser : DalUser
{
[Display(Name="ID Code")]
public override int Id { get; set; }
[Display(Name="Age")]
[Required]
public override int Age { get; set; }
}
这让我有两个目标:前者是我可以使用属性而不用担心破坏其他东西,后者是我可以向用户隐藏某些字段,防止现场注入(例如来自FireBug - 但这包括定义接口和使用它,而不是普通的子类)。
这证明在我的公司内部非常有用(我们注定要使用EntitySpaces),这是我为了部分重用ES生成的类而找到的一种不那么丑陋的方法。