在app服务中注入infra图层界面

时间:2011-05-08 18:05:59

标签: domain-driven-design

我有两个聚合,广告客户和付款。

我正在使用Paypal和Authorize.net支付网关。所以我在infra层创建了界面。

interface IPaymentMethod
{
   void ProcessPayment(PaymentInfo paymentInfo);
}

并在infra层再次实现。

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);
    }
}

在App层中 - 我可以在App层构造函数中注入PaypalMethod接口并在DepositFundInAdvertiser方法中执行以下操作吗?

请记住,IPaypalMethod是在infra层中创建和实现的。

2 个答案:

答案 0 :(得分: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
  }
}

答案 1 :(得分:1)

跟进我的评论。我还将PaymentService作为基础结构服务放在基础架构层中。但正如Arnis所说,你也应该反映这个模型对这个行动的反应 - 支付。

我(不确定)可能在应用服务层中有某种类型的PaymentService,它适用于实体广告商和付款(通过IAdvertiserRepository和通过构造函数注入的IPaymentRepository)。

在方法中(在memcode中编写此方法): PaymentService.PayAdvert(广告商广告商,广告广告,付款paymentInfo) { advertiser.BuyAdvertising(AdvertPayment.Create(广告,paymentInfo)) }

BuyAdvertising方法将广告和付款同时纳入AdvertPayment类(对于ctor本身具有静态创建方法。如果您希望广告商的PaymentHistory集合按日期顺序包含AdvertPayments,则此类可以很方便。但是 BuyAdvertising提出了一个域事件BuyAdvertisingEvent,它触发应用程序层中的事件处理程序BuyAdvertisingEventHandler。

这个Eventhandler在构造函数中注入了你的IPaypalGatewayService。有了这个活动,我们有付款信息。如果付款成功,则EventHandler还可以在ctor中注入IAdvertiserRepository,并将AdvertPayment保存到广告商付款历史记录集合中。

然后,BuyAdvertising可以通过检查广告是否已付款并添加到历史记录集合来确定付款交易的结果。

我希望你能得到这张照片。这样,您就可以使用多种工具,例如在域模型中声明并从实体广告商触发的事件。该模型采取行动,你已经通过DomainEventHandler移动了针对PayPal的基础技术逻辑,你还没有将逻辑完全放在应用层。控件位于域中,但域不关心的详细信息放在infra层中。

我的经验是,这些场景对我来说很常见,你通常会采用简单的方法,让应用程序服务与infralayer进行交流。但是,你正在关闭一个贫血的模型设计,因为该模型还需要做什么?只是验证属性?只管理聚合和集合?我认为还有更多。它还应该包含很多实体操作方法(我称之为...... :),如BuyAdvertisment。

/干杯