在应用程序服务中注入基础层接口
我有两个聚合:广告商和付款。
我正在使用 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 是在基础层中创建和实现的。
I have two aggregates, Advertiser and Payment.
I am using Paypal and Authorize.net payment gateway. So i created interface in infra layer.
interface IPaymentMethod
{
void ProcessPayment(PaymentInfo paymentInfo);
}
and implemented it again in infra layer.
Public class PaypalPaymentGateway : IPaymentMethod
{
public void ProcessPayment(PaymentInfo paymentInfo)
{
// call Paypal api and pass paymentinfo
}
}
//same for authorize.net payment gateway
Below is my app service class
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);
}
}
In App layer - can I inject PaypalMethod interface in App layer constructor and do the following in DepositFundInAdvertiser method?
Remember IPaypalMethod is created and implemented in infra layer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的方法似乎足够好。
只有我会在域层而不是基础设施层中定义
IPayer
抽象。因为领域模型(很可能)有责任决定支付不成功时如何反应。
Your approach seems good enough.
Only I would define
IPayer
abstraction inside domain layer instead of infrastructure layer.Because it's (most likely) responsibility of domain model to decide how to react if payment is [un]successful.
跟进我的评论。我还将 PaymentService 作为基础设施服务放在基础设施层中。但正如阿尼斯所说,你还应该反映模型如何响应此操作 - 支付。
我(不确定)可能会在应用程序服务层中有某种 PaymentService,它可以与广告商和支付实体一起使用(通过构造函数注入 IAdvertiserRepository 和 IPaymentRepository)。
方法中(将这个方法写在memcode中):
PaymentService.PayAdvert(广告商广告商、广告广告、付款 paymentInfo)
{
广告商.BuyAdvertising(AdvertPayment.Create(广告, paymentInfo))
BuyAdvertising 方法将 Advert 和 Payment 放入 AdvertPayment 类(该类本身有一个 ctor 的静态创建方法)。如果您想要包含按日期顺序排列的
AdvertPayments 的 Advertiser PaymentHistory 集合,则该类会很方便。但是
BuyAdvertising 引发域事件 BuyAdvertisingEvent,该事件触发应用程序层中的事件处理程序 BuyAdvertisingEventHandler。
此事件处理程序将您的 IPaypalGatewayService 注入到构造函数中。通过该活动,我们有付款信息。如果支付成功,EventHandler 还可以将 IAdvertiserRepository 注入到 ctor 中,并将 AdvertPayment 保存到广告商支付历史记录集合中。
然后BuyAdvertising可以通过检查广告是否已支付并添加到历史集合来确定支付交易的结果。
我希望你能明白这张照片。这样,您就拥有了多个工具,例如在域模型中声明并从实体广告商触发的事件。该模型采取行动,您已经通过 DomainEventHandler 将针对 PayPal 的基础技术逻辑移出,但您还没有完全将逻辑定位在应用程序层中。控制位于域中,但域不关心的细节放置在下层。
我的经验是,这些场景对我来说很常见,您通常会采取简单的方法,让应用程序服务与底层进行所有对话。但接下来你就要接近贫血的模型设计了,因为模型还剩下什么要做呢?只是验证属性?只是管理聚合和集合?我认为还有更多内容。它还应该包含许多实体操作方法(我这样称呼它们......:)),例如 BuyAdvertisment。
/干杯
To follow up on my comment. I would also put the PaymentService in infrastructure layer as an infrastructure service. But as Arnis said you should also reflect ho the model respond to this action - Pay.
I (not sure) would probably have some kind of PaymentService in applicaion service layer that works with both entities Advertiser and Payment (through IAdvertiserRepository and IPaymentRepository injected through constructor).
In method (writing this method in memcode):
PaymentService.PayAdvert(Advertiser advertiser, Advert advert, Payment paymentInfo)
{
advertiser.BuyAdvertising(AdvertPayment.Create(advert,paymentInfo))
}
BuyAdvertising method takes both Advert and Payment into AdvertPayment class (which has a static create method for ctor itself. This class can be handy if you want a PaymentHistory collection for Advertiser that contains AdvertPayments in date order. But
BuyAdvertising raises a domain event BuyAdvertisingEvent that triggers a eventhandler in application layer, BuyAdvertisingEventHandler.
This Eventhandler has your IPaypalGatewayService injected in constructor. With the event we have Payment info. If Payment is a success the EventHandler can also have IAdvertiserRepository injected in ctor and save the AdvertPayment into Advertiser payment history collection.
then BuyAdvertising can determine the outcome of payment transaction by checking if advert is paid and added to history collection.
I hope you get the picture. This way you have several tools like an event which is declared in domain model and triggered from the entity advertiser. The model takes action and you have moved out the infra tech logic against PayPal through DomainEventHandler an still, you have not located the logic entirely in application layer. The control is in the domain, but details that domain don't care about is placed in infra layer.
My experience is that these scenarios are common for me and you usually go the easy way, letting the application service do all talking to infralayer. But then you're closingin on a anemic model design, because what is left for the model to do? Just validation properties? Just managing aggregates and collections? I think there is more to it. It should also contains a lot of entity action methods (I call them so... :)) like BuyAdvertisment.
/Cheers