上一次(即昨天),我們完成了業務邏輯層的演示;傳送門:項目架構開發:業務邏輯層之領域驅動失血模型
設計上雖然還不是太優雅,但是距離真正的OO編程又更近了一步,而且也保留了事務腳本模式的簡單快捷的特性
只要后續把Model層豐富起來,那就算是掌握了另一種軟件開發模式,而且也是整個思想上的轉變。
本章我們來完成在業務邏輯層之上的服務層;
服務層並不是必須的,在有一定復雜度的應用程序中,服務層非常有必要創建;而與之相反的就是,
在一些業務邏輯簡單的系統中,服務層可能僅僅充當分發功能,沒有多余的工作需要組織,這時服務層就顯得多余;
而且,服務層一般還與客戶端有關系(Web、Winform);如果是Web,在同一系統內,服務層就沒有大多必要,除非是跨系統的服務調用;
如果是Winform,那服務層就比較常用,因為Winform是C/S模式,物理層上天生與服務器端分離。
若是從C端遠程調用應用邏輯,那有可能在長距離的遠程調用中花費太多的時間,而加入服務層情況就會不同
服務層就是為UI何應用邏輯層之間提供一個數據交互的契約,簡單點說就是從C端發送一組參數,在S端進行邏輯運算,
因為一般情況下S端與數據庫在同一局域網下,訪問速度比前者快很多,效率也大大提高
若沒有服務層,則需要從UI直接與后端應用程序通信,交互次數大大的增加,通信距離也大大的影響程序性能
我們開始吧。
1、應用邏輯,創建新登錄用戶

1 public bool Add(AddRequest entity) 2 { 3 this.repository.Add(new LoginUser() 4 { 5 Id = Guid.NewGuid(), 6 LoginName = entity.LoginName, 7 Password = entity.Password, 8 IsEnabled = entity.IsEnabled, 9 CreateTime = DateTime.Now 10 }); 11 this.unitOfWork.Commit(); 12 13 return true; 14 } 15 16 public bool Check(string loginName) 17 { 18 return this.repository.Count(w => w.LoginName == loginName) > 0; 19 }
這里添加了2個方法,功能不解釋了
現在,我們假設UI層與應用層相距甚遠,那直接調用顯然是不妥的,我們創建一個服務項目來完成這個功能
2、新建WCF項目

IUserService.cs
1 [ServiceContract] 2 public interface IUserService 3 { 4 [OperationContract] 5 bool Add(AddRequest entity); 6 7 [OperationContract] 8 UserList GetAll(); 9 } 10 11 [DataContract] 12 public class UserList 13 { 14 [DataMember] 15 public IEnumerable<GetAllResponse> Items { get; set; } 16 }
UserService.svc
1 public class UserService : IUserService 2 { 3 public bool Add(AddRequest entity) 4 { 5 var loginUserApp = new LoginUserApplication(); 6 if (loginUserApp.Check(entity.LoginName)) 7 { 8 throw new Exception("登錄名稱已被占用!"); 9 } 10 11 loginUserApp.Add(entity); 12 return true; 13 } 14 15 public UserList GetAll() 16 { 17 var loginUserApp = new LoginUserApplication(); 18 var wcf = new UserList(); 19 wcf.Items = loginUserApp.GetAll(); 20 21 return wcf; 22 } 23 }
也很簡單明了,在Add方法中我們完成以后的校驗與新增
3、新建客戶端測試項目

UserService.cs

這個類是系統自動生成的,不用我們自己寫
Program.cs
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var userClient = new UserServiceClient(); 6 var addRequest = new Business.DTO.Request.AddRequest() 7 { 8 LoginName = "LoginName" + Guid.NewGuid().ToString(), 9 Password = "Password", 10 IsEnabled = 1 11 }; 12 userClient.Add(addRequest); 13 Console.WriteLine(string.Format("Add finish: {0}", addRequest.LoginName)); 14 15 var result = userClient.GetAll(); 16 foreach (var item in result.Items) 17 { 18 if(item.LoginName == addRequest.LoginName) 19 Console.WriteLine(string.Format("Found you: {0}", item.LoginName)); 20 } 21 22 Console.WriteLine("totle:" + result.Items.Count()); 23 Console.WriteLine(); 24 25 Console.ReadKey(); 26 } 27 }
看看效果

成功了啊
上邊演示的是適合C/S架構,我們再來看看B/S的
4、新建WebApi

UserController.cs
1 public class UserController : ApiController 2 { 3 public IEnumerable<GetAllResponse> GetAll() 4 { 5 var loginUserApp = new LoginUserApplication(); 6 return loginUserApp.GetAll(); 7 } 8 9 public HttpResponseMessage Get(Guid id) 10 { 11 var loginUserApp = new LoginUserApplication(); 12 LoginUser loginUser = loginUserApp.Get(id); 13 if (loginUser == null) 14 { 15 return Request.CreateResponse(HttpStatusCode.NotFound); 16 } 17 18 return Request.CreateResponse(loginUser); 19 } 20 21 public bool Add(AddRequest user) 22 { 23 var loginUserApp = new LoginUserApplication(); 24 if (loginUserApp.Check(user.LoginName)) 25 { 26 throw new Exception("登錄名稱已被占用!"); 27 } 28 29 return loginUserApp.Add(user); 30 } 31 }
UserControllerTest.cs
1 public void Add() 2 { 3 var userController = new UserController(); 4 var flag = userController.Add(new AddRequest() 5 { 6 LoginName = "LoginName" + Guid.NewGuid().ToString(), 7 Password = "Password", 8 IsEnabled = 1 9 }); 10 11 Assert.AreEqual(true, flag); 12 } 13 14 [TestMethod] 15 public void GetAll() 16 { 17 var userController = new UserController(); 18 var list = userController.GetAll(); 19 int count = list.Count(); 20 21 Assert.AreEqual(true, count > 0); 22 }
運行看看效果

看來沒什么問題,成功了
看看完整架構

