2011-05-08 51 views
0

我有兩個聚合,廣告商和付款。在應用服務中注入底層接口

我使用的是Paypal和Authorize.net支付網關。所以我在底層創建了接口。

interface IPaymentMethod 
{ 
    void ProcessPayment(PaymentInfo paymentInfo); 
} 

並在底層再次實現它。

Public class PaypalPaymentGateway : IPaymentMethod 
{ 
    public void ProcessPayment(PaymentInfo paymentInfo) 
    { 
     // call Paypal api and pass paymentinfo 
    } 
} 

//同爲authorize.net支付網關 下面是我的應用程序服務類

public class PaymentGatewayService : IPaymentGatewayService 
{ 

    IPaypalMethod paypalMethod; 

    public PaymentGatewayService(IPaypalMethod paypalMethod) 
    {    
     this.paypalMethod = paypalMethod; 
     if (paypalMethod == null) 
      throw new Exception("PaypalMethod not initialized"); 
    } 

    public void DepositFundInAdvertiser 
     (PaymentInfo paymentInfo, RegistrationID advertiserRegistrationID) 
    { 
     if (paymentMethod != null)    
      throw new Exception("PaymentMethod empty."); 

     PaymentResult paymentResult= 
      paymentMethod.ProcessPayment(paymentInfo); 
     Advertiser advertiser = advertiserRepository 
      .Find(advertiserRegistrationID); 
     advertiser.AddAdvertiserFund(paymentInfo.PaymentTotal); 
     advertiserRepository.Save(advertiser); 
    } 
} 

在應用層 - 我可以在注入層應用程序構造PaypalMethod接口和做DepositFundInAdvertiser方法如下?

記住IPaypalMethod是在底層創建和實現的。

回答

1

你的方法似乎足夠好。

只有我會在域層中定義IPayer抽象而不是基礎設施層。

因爲如果付款是[非]成功的,域模型的(最有可能的)責任就是決定如何反應。

//in domain model 
public class IPayer{ 
    bool Pay(Money amountToBePaid, BankAccount account);; 
} 
public class Payment{ 
    public void Pay(IPayer payer){ 
    EnsurePaymentCanBePaid(); 
    IsPaid=payer.Pay(AmountToBePaid,Account); 
    if(!IsPaid) throw new Exception("Payment failed!"); 
    } 
} 
//in infrastructure layer 
public class PayPalPayer:IPayer{ 
    public bool Pay(Money amountToBePaid, BankAccount account){ 
    //bla bla 
    } 
} 
+0

「只有我會定義域層,而不是基礎設施層內IPayer抽象。」你的方法,是我以前做過,但我的同事告訴我,像IPaymentRepository我們因此未在我們的領域注入,但使用應用程序服務來處理所有,同樣在這裏,他也反對在域模型中注入IPayer。他告訴我,它緊密耦合或域名,他也給我的網址,它被阻止在域模型中注入IPaymentRepository。請建議我有效的點數,以便我可以將它們提供給我的同事。 – kamal 2011-05-09 10:05:26

+1

模型應該是持久的無知。因此 - 它應該對存儲庫一無所知。但支付能力是一個領域問題,因此 - 它應該生活在領域。至少我是這麼看的。 – 2011-05-09 10:59:50

+0

我同意你的同事。在應用服務層中注入IPaymentRepository。但阿爾尼斯有一點。領域層應該模擬現實,並且這是在付款成功或不成功時採取的行動。通知付款人/用戶,打印筆記等。看到我的回答如下... – 2011-05-09 11:16:15

1

要跟進我的評論。我還會將PaymentService作爲基礎架構服務放入基礎架構層。但正如阿爾尼斯所說,你也應該反映這種模式對這一行爲的反應 - 支付。

我(不知道)可能會在應用程序服務層中有某種PaymentService與廣告客戶和付款實體(通過通過構造函數注入的IAdvertiserRepository和IPaymentRepository)一起工作。

在方法(寫入memcode此方法): PaymentService.PayAdvert(廣告客戶的廣告客戶,廣告廣告,付款paymentInfo) { advertiser.BuyAdvertising(AdvertPayment.Create(廣告,paymentInfo)) }

BuyAdvertising方法將廣告和付款都放到AdvertPayment類中(對於ctor本身有一個靜態的創建方法,如果您希望廣告商的PaymentHistory集合按廣告日期順序包含AdvertPayments,則該類可能非常方便,但 BuyAdvertising會引發一個域事件BuyAdvertisingEvent觸發應用程序層中的事件處理程序BuyAdvertisingEventHandler。

此事件處理程序已將IPaypalGatewayService注入到構造函數中。隨着事件我們有付款信息。如果付款成功,EventHandler也可以將IAdvertiserRepository注入到ctor中,並將AdvertPayment保存到廣告客戶付款歷史記錄集合中。

然後購買廣告可以通過檢查廣告是否支付並添加到歷史收藏中來確定支付交易的結果。

我希望你能得到照片。這樣,您就有了幾個工具,例如在域模型中聲明並由實體廣告客戶觸發的事件。該模型採取行動,您已經通過DomainEventHandler將PayPal的技術邏輯移出,但您尚未完全在應用程序層中定位邏輯。該控件位於域中,但域不關心的細節放置在底層。

我的經驗是,這些場景對我來說很常見,而且你通常會輕而易舉地讓應用服務與infralayer進行通話。但是,那麼您是在關注貧血模型設計,因爲模型需要做些什麼?只是驗證屬性?只是管理集合和集合?我認爲還有更多。它還應該包含很多實體操作方法(我稱之爲... :)),比如BuyAdvertisment。

/乾杯