2017-05-26 30 views
2

該問題集中在依賴注入和通用接口上。根據基本通用類型調用正確的通用接口實現

我的一個商業實體是身份證。可以有多種類型的ID卡,全部來自ICard繼承:

interface ICard 
{ 
    string CardId { get; } 
} 

class CardA : ICard 
{ 
    string CardId { get; set; } 
    string SomethingCardASpecific { get; set; } 
} 

class CardB : ICard 
{ 
    string CardId { get; set; } 
    bool SomethingCardBSpecific { get; set; } 
} 

我有一個CardFactory,需要一個卡ID,並返回正確的卡類型(ICard):

class CardFactory : ICardFactory // Trivial interface definition left out 
{ 
    ICard FromCardId(string cardId) 
    { 
     if (MatchesPatternA(cardId)) 
     { 
      return new CardA { CardId = cardId /* ... */ } 
     } 
     else 
     { 
      return new CardB { CardId = cardId /* ... */ } 
     } 
    } 
} 

此外,我有另一個依賴關係,檢查卡是否被授權執行某些操作。該邏輯依賴於卡片的類型,因此,通用的接口:

interface ICardAuthorization<TCard> where TCard : ICard 
{ 
    bool IsOperationXPermitted(TCard card); 

    bool IsOperationYPermitted(TCard card); 
} 

我有取決於ICardFactoryICardAuthorization一個API控制器。一個動作收到cardId,創建一張卡片,並檢查它是否被授權採取行動X.控制器不關心兩種卡片類型授權的處理方式不同,因此它應該取決於「基本」卡片上的操作類型(接口),即ICardAuthorization<ICard>

實際問題:

當然,我需要的ICardAuthorization至少兩種不同的實現,即

class CardAAuthorization : ICardAuthorization<CardA> { /* ... */ } 
class CardBAuthorization : ICardAuthorization<CardB> { /* ... */ } 

然而,使用上述的設計中,API需要依賴的接口上輸入到ICard

class DelegatingCardAuthorization : ICardAuthorization<ICard> { /* ... */ } 

這,反過來,d依靠兩個「真正」的主力,ICardAuthorization<CardA>和​​,並根據其方法接收的ICard的類型調用正確的。

當然,在我的應用程序中,ICardAuthorization<TCard>只是需要針對不同卡類型實施不同卡的幾種接口之一。

在我看來,這似乎是一種相當健壯的方式來構建事物,但我不喜歡這樣一個事實,即我需要委託實現來檢查類型並將調用轉發給其他實現。我可以忍受它,沒問題,但是否有任何方法通過消除委託實現的需要來使這更優雅?(我正在使用SimpleInjector,如果重要的話)。

+0

您可以詳細介紹一張卡創建後會發生什麼?它是否直接返回到web api客戶端?還是進一步傳遞到某種業務層? –

+0

它不會返回給客戶端,它僅用於業務層以識別用戶。 – cmeeren

回答

1

我想你不能完全刪除委託實現的需要,因爲選擇基於卡類型的動作的邏輯應該駐留在某處。

然而,我提出的是與工廠同行。

創建CardAuthorizationFactory這將根據傳遞給它的ICard對象的類型返回適當的ICardAuthorization實現者。爲其他卡片操作創建任意數量的其他工廠。把所有這些作爲單身人士加入IoC。

現在,當某些方法需要使用授權對某張卡片進行操作時,它應該查詢AuthorizationFactory以獲取適合當前卡片對象的CardAuthorization對象。工廠應該由IoC注入。它會滿足你的需求嗎?

+0

謝謝!我看不出這對代表有什麼好處。類的數量是相同的,這將需要一個更多的接口(用於工廠)。但謝謝你的建議。 :) – cmeeren

+0

@cmeeren至少我看到的一個好處是,工廠比習慣授權類更有名。 –

+1

當然,這是一個公平的觀點。 – cmeeren