jNet
jNet

Reputation: 143

Where should be my logic Service Layer OR Controller

I am looking for help in deciding where should I write my logic. I want to write unit tests as well.

I am getting an Order and I have to insert this order into db.

my Order model :

public class CustomerView
{
    public int id { get; set; }
    public string first_name { get; set; }
    public string last_name { get; set; }
    public string email { get; set; }
    public string primary_email_address { get; set; }
    public string image { get; set; }
}

public class ProductView
{
    public int id { get; set; }
    public string name { get; set; }
}

public class LineView
{
    public int number { get; set; }
    public ProductView product { get; set; }
    public int quantity { get; set; }
    public double? price_variation { get; set; }
    public List<int?> modifiers { get; set; }
    public string notes { get; set; }
    public double unit_price { get; set; }
    public double unit_tax { get; set; }
}

public class MethodView 
{
    public int id { get; set; }
    public string name { get; set; }
}

public class PaymentView
{
    public int id { get; set; }
    public int number { get; set; }
    public MethodView method { get; set; }
    public double amount { get; set; }
    public double tip { get; set; }
    public string created_at { get; set; }
}

public class Order
{
    public int id { get; set; }
    public string sale_number { get; set; }
    public string status { get; set; }
    public string notes { get; set; }
    public double total { get; set; }
    public double paid { get; set; }
    public double tips { get; set; }
    public int register_id { get; set; }
    public int site_id { get; set; }
    public List<LineView> lines { get; set; }
    public double price_variation { get; set; }
    public List<PaymentView> payments { get; set; }
    public string callback_uri { get; set; }
//    public List<string> @lock { get; set; }
    public int staff_member_id { get; set; }
    public string placed_at { get; set; }
    public string fulfil_at { get; set; }
    public string created_at { get; set; }
    public string updated_at { get; set; }


    public CustomerView Customer { get; set; }
}

From this model I have to Check:

  1. If SiteID is in DataBase
  2. If NOT in DB, fetch the complete site info from third party API and save into my DB
  3. IF Site Exists, simply fetch the details
  4. Check if Customer exists in my DB.
  5. If Not Exists - get the customer info from third party API and save into my DB
  6. If Exists, simply get it from my DB
  7. Finally, Save this order

I am using Repository Pattern, EF code first and IoC AutoFac and AutoMapper in my project. I also want to write Unit Tests of the above stated Business Logic.

My confusion is:

Should I write above logic my Controller - for example: I should build my DB model from the controller by applying my above checks and simply pass it to Order Service where I will simply save my model

OR

Should I write all the above checks in Business Layer ( Order Service ) - For example - pass a DTO object from Controller to the service and all the other checks in the Service Layer?

Many thanks,

Upvotes: 1

Views: 1330

Answers (2)

Rob Conklin
Rob Conklin

Reputation: 9456

The way I like to decide whether logic belongs in a service/domain vs. a controller layer is whether I would throw this logic away if I were building a thick-client version of this application.

If I would keep this logic, then it has nothing to do with application flow, and should be encapsulated in a service layer (and of course you unit test your business service and domain layer).

If I would throw this logic out, it probably belongs to the controller layer, as it probably is tied to the application flow (which is very different in a website vs a thick client).

This logic seems firmly in the first camp, you would keep it, and as such it should go into your service or domain layer.

Upvotes: 3

Ivan Gerken
Ivan Gerken

Reputation: 914

In general I strive to put all if-s and switch-es into the testable code, i.e. in controllers, and keep the code of the rest (views, services, etc.) as simple/straightforward/trivial as possible.

So I'd put those checks into a controller unless I had a good reason not to do so (e.g. minimizing roundtrips to database)

Upvotes: 0

Related Questions