2016-11-29 153 views
0

我正在創建一個可以調用服務層的Web API,並且我正在嘗試學習依賴注入(我希望使用ninject),但我不確定如何在服務上創建依賴關係層。服務層依賴注入

這是web api會調用的。

enter image description here

這裏的問題,要求IPersonService時,人就會有性別定義,這將有一個名稱,角色和種族。我正在使用構造函數注入,並且不確定是否應該調用GenderService,還是應該調用業務層(在這種情況下,由Core定義)。

enter image description here

我應該打電話喜歡的圖片服務高於或低於

enter image description here

這是我一個人服務的樣子

namespace Service.Services 
{ 
    public class PersonService : IPersonService 
    { 
     private IPersonCore personCore = null; 
     private INameService nameService = null; 
     private IRoleService roleService = null; 
     private IGenderService genderService = null; 
     private IEthnicityService ethnicityService = null; 
     private IPrefixService prefixService = null; 
     private Person currUser; 

     public PersonService(IPersonCore _personcore, INameService _namecore, IRoleService _roleservice, IGenderService _genderservice, IEthnicityService _ethnicityservice, IPrefixService _prefixservice) 
     { 
      this.personCore = _personcore; 
      this.nameService = _namecore; 
      this.roleService = _roleservice; 
      this.genderService = _genderservice; 
      this.ethnicityService = _ethnicityservice; 
      this.prefixService = _prefixservice; 
     } 

     public IEnumerable<Person> GetAllPerson() 
     { 
      if (isAuthorized()) 
      { 
       return this.personCore.GetPersons(); 
      } 
      return null; 
     } 

     public Person GetPersonByID(int id) 
     { 
      if (isAuthorized()) 
      { 
       return this.personCore.GetPersonByID(id); 
      } 
      return null; 
     } 

     public Person GetPersonByEmail(string email) 
     { 
      if (isAuthorized()) 
      { 
       return this.personCore.GetPersonByEmail(email); 
      } 
      return null; 
     } 

     public IEnumerable<Person> GetPersonByName(string first, string last, string middle) 
     { 
      if(isAuthorized()) 
      { 
       Name newname = this.nameService.CreateName(first, last, middle); 
       return this.personCore.GetPersonByName(newname); 
      } 
      return null; 
     } 

     public IEnumerable<Person> GetPersonWithRoles(IEnumerable<Roles> r) 
     { 
     } 

     public IEnumerable<Person> GetPersonWithDOB(DateTime d) 
     { 
      if (isAuthorized()) 
      { 
       return this.personCore.GetPersonWithDOB(d); 
      } 
      return null; 
     } 

     public Person SetPersonRole(int id, Roles r) 
     { 
     } 

     public Person SetGender(int id, Gender g) 
     { 
     } 

     public Person SetEthnicity(int id, Ethnicity e) 
     { 
     } 

     public Person SetPrefix(int id, Prefix p) 
     { 
     } 

     public Person CreatePerson(Person p) 
     { 
      if (isAuthorized()) 
      { 
       return personCore.AddPerson(p); 
      } 
      return null; 
     } 

     public Person UpdatePerson(Person p) 
     { 
      if (isAuthorized()) 
      { 
       return personCore.UpdatePerson(p); 
      } 
      return null; 
     } 

     public Person ActivatePerson(int id) 
     { 
      if (isAuthorized()) 
      { 
       return personCore.ActivatePerson(id); 
      } 
      return null; 
     } 

     public Person DeactivatePerson(int id) 
     { 
      if (isAuthorized()) 
      { 
       return personCore.DeactivatePerson(id); 
      } 
      return null; 
     } 

     public bool DeletePerson(int id) 
     { 
      if (isAuthorized()) 
      { 
       return personCore.DeletePerson(id); 
      } 
      return false; 
     } 

     protected bool isAuthorized() 
     { 
      //Probably move to common 
      return true; 
     } 
    } 
} 

從撥打電話時Web API是我的問題,它的聲音就像尋找某人某事的依賴性。

回答

1

您可以通過兩種方式簡化了這一點:

  1. 您PersonService看起來並不取決於本身的角色,性別,種族和前綴服務,您不要從它的方法調用它們。它是客戶端代碼調用的一個shell,而不是直接調用這些服務。如果是這樣的話,那麼你可以通過獲取這些4只依賴了簡化PersonService:

    private IRoleService roleService = null; 
    private IGenderService genderService = null; 
    private IEthnicityService ethnicityService = null; 
    private IPrefixService prefixService = null; 
    

    而且這些方法了各自的服務:

    public Person SetPersonRole(int id, Roles r) 
    { 
    } 
    public Person SetGender(int id, Gender g) 
    { 
    } 
    public Person SetEthnicity(int id, Ethnicity e) 
    { 
    } 
    public Person SetPrefix(int id, Prefix p) 
    { 
    } 
    
  2. 如果您需要完全保留這些方法在你的IPersonService中,那麼你會注入依賴關係的方法而不是構造函數。

    關於服務或核心的依賴關係,它取決於您的服務的功能。如果你的服務只是調用核心,那麼你自己去核心。如果您的服務正在進行一些驗證或其他任何事情,您可能需要依賴它來避免複製PersonService中的相同代碼。

1

PersonService類包含很多依賴項,因爲您違反了Single Responsibility Principle。這個班級有許多責任,每當你添加一個新功能(這是違規行爲Open/Closed Principle),你最終都會改變這個班級。此外,isAuthorized方法是一個交叉問題,這個類應該沒有概念。

最重要的是,您正在將當前登錄的用戶注入PersonService。這是運行時數據,並且是constructing application components using runtime data is an anti-pattern

有很多方法可以解決這個問題,但這一切都歸結爲理解SOLID原則。但是,這樣做可能是一項艱鉅的任務,特別是如果您剛開始使用DI和軟件設計。有很多書可以閱讀,例如Robert C. Martin的the amazing work和有關依賴注入的書籍,如Mark Seemann的Dependency Injection in .NET

最近幾年幫助我的設計是基於消息的體系結構,其中用例通過消息描述,實現通過通用抽象描述(讀取thisthis)。這些設計被證明是非常靈活和可維護的,因爲它們允許透明地添加橫切關注點並允許添加新功能而不更改任何現有代碼。這種設計還可以將您的Web API層簡化爲一個簡單的基礎結構,在添加新功能時不需要更改。你可以閱讀關於這個概念here(注意:該文章是關於WCF,但Web API的概念是相同的),並且here是一個Github存儲庫,展示瞭如何在WCF和Web API中實現這一點。

祝您在尋求軟件精通方面一切順利。

+0

謝謝,所以從用戶角度來看,Personservice應該返回基本的id,密碼,電子郵件但是角色,性別只應該給genderService,兩個服務不應該互相對話? – Jseb

+0

@Jseb:這不是我所宣傳的。我正在推廣的是一個模型,其中每個查詢(例如'GetAllPerson'和'GetPersonByEmail')都包含在它自己的類中。這樣的類可以依賴於它所需要的東西,但在大多數情況下只會使用'DbContext'來查詢數據庫。 – Steven