Base solution for your next web application
Open Closed

DDD Question For Anz #10913


User avatar
0
cangunaydin created

Hello, I have a general question about AspnetZero design, and some use case about my implementation. First of all i want to ask: If i look at the Core project of the ANZ, i see that Stripe, Paypal is directly dependent to this project. isn't this actually against the domain driven design? since the core (domain) project shouldn't have any other dependency? or maybe i am missing sth over here but it would be good if you can explain why ANZ choose this way?

Actually i have a similar case like payment model that you have implemented, and i couldn't figure out how to make it possible according to design patterns. My requirement includes different economy systems to be involved in my application. We need to have Oracle Netsuite and Fortnox implementation and maybe more in the future for the tenants to invoice their clients

So as an example Tenant A can use Oracle Netsuite, Tenant B can use Fortnox and some tenants can use different economy system for the invoicing. So i have implemented a new module for Oracle Netsuite now i want to plug in this module but here are some difficulties for it.

  1. Since Oracle Netsuite Module dependent on a soap service, it returns classes that is spesific for the netsuite.
  2. It has different services like NetsuiteCustomerService,NetSuiteSalesOrderService and so on. We have implemented interfaces for this in the same module. According to DDD, this project should be dependent on the infrastructure project and infrastructure project should be dependent on the core project. So here is the question, is the infrastructure project is EntityFrameworkCore and Application Project (like 2 different infrastructure) or is the infrastructure project is only EntityFrameWorkCore project? I am kind of confused here since both EntityFrameworkCore and Application project is referencing to core project. But on the other hand application project seems like it is doing the job of the presentation layer and working like an orchestrator. So how should i think of the application project as second infrastructure project or the extension of the web project?
  3. I keep Oracle Netsuite Module as seperate project so it does not have any dependency only a soap reference that it has. So one way to achieve what i am trying to do is create another seperate project just like entityframeworkcore project, and make this reference to core project, on the core project implement some abstraction like general interface sth like

IAccountingOrderService Task<bool> CreateInvoice(Order order); //Order is an entity

IAccountingCustomerService Task<Dictionary<string,string>> GetCustomers();

and then do the implementation in this new seperate project, so i can reference the nuget packages or modules in this project. And according to tenant configuration, I can use the convenient economy system to create invoicing and getCustomers from specific economy system. With this method i am not coupling my oraclenetsuite module with core project but it means to create another infrastructure project. I couldn't be sure this is gonna be the right way? Or maybe i should directly give the reference to the application project and CreateInvoice in the application service? Can you give me some idea how should i approach to the problem? thank you for the assistance.


8 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @cangunaydin

    I think your approach seems better. We decided to place Payment gateways in this way not to make the project more complicated. Also, it was not easy to make a common interface for both Stripe and Paypal. But, for your case, you can continue using this approach to separete implementation from your domain logic.

  • User Avatar
    0
    cangunaydin created

    Hello @ismcagdas, thanks for your answer, what do you think about application service question? why shouldn't i reference my oracle netsuite project directly to application service and create the implementation over there like EPPlus you did? what can be the benefit of creating the seperate project?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @cangunaydin

    Sorry for my late reply. I couldn't understand which approach you mention here. Could you explain it in details ? Sorry, I just didn't want to give you a false information without fully understand your requirement.

  • User Avatar
    0
    cangunaydin created

    Sure, I am posting couple of drawings here to show what i mean

    here with the red dashes is what i am trying to create and when i say infrastructure project i am referring to

    and this one https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

    so basically infrastructure for me is all the implementations take place with the abstractions of your domain model. So since application service also dependent on your core project (domain model) i was thinking, is it possible to do the implementation on application layer? Or what will be the problems with it? Cause when i think about it, some tenants don't need to use invoicing at all. Isn't this a business rule to choose which invoicing platform should the tenant use?

    At the same time some tenants in aspnet zero don't need to use payment services at all, but still implementations are on the domain model and it's strictly connected to your domain. Actually what i am trying to find out is, i understand your payment can not have general abstraction for stripe and paypal, but what if it has, how smart would be to do the implementation on application service? or what kind of problems would it bring?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @cangunaydin

    The infrastructure layer is not relatead to your domain at all. It is the technology dependent layer in your app. For example EF Core allows you to connect with a database but if you change your DB to Oracle, it doesn't change your domain, you only change a technology. So, you can create such a Invoicing project but it will divide your Core (Domain) project into multiple projects.

    On the other hand, App layer is responsible for communication between Presentation and Domain Layers. You can take a look at https://aspnetboilerplate.com/Pages/Documents/NLayer-Architecture#domain-driven-design-layers for more info.

    So, I think your your case, you correctly created the Invoicing project. But, it is sometimes hard to make such decisions and you can always change it in the future depending on your app's needs.

  • User Avatar
    0
    cangunaydin created

    Hello @ismcagdas, Thank you for the answer actually invoicing is bad naming coming from me i believe. maybe i should say EXTERNAL SYSTEMS instead or sth more convenient for the naming.

    The module i am gonna implement is gonna be responsible for the implementations. So factory classes gonna be in EXTERNAL SYSTEMS. interfaces are gonna be inside CORE.

    in this way i can use the interfaces from CORE and implement it on the EXTERNAL SYSTEMS.

    EXTERNAL SYSTEMS can be dependent on different invoicing modules like Oracle Netsuite Module that i have created or Fortnox or different nuget packages for different invoicing systems. So i will do the decision for implementation at this module by using the interfaces from CORE.

    sth like this maybe more convenient.

    Note: I only created oracle netsuite project not the EXTERNAL SYSTEMS project yet :)

    So i think what i want to ask is, Since i am gonna do conditional dependency resolve, my core project needs to know about what kind of interfaces i am going to use. here is some drawing i made for it.

    so the question is, is it possible to use only IInvoicingService inside core somehow?

    Sorry for lots of questions, I am also learning on the way and i really appreciate the assistance and help.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    I think you can define IInvoicingServiceFactory in the Core project and implement it in the External System project. Then, in core project, you can use IInvoicingServiceFactory to get an instance of IInvoicingService. Does that work for you ?

  • User Avatar
    0
    cangunaydin created

    yes silly me, thanks for the answer and sorry to take your time.