Alex Ivan
Alex Ivan

Reputation: 95

Where to implement business logic in .NET Core Web API?

I am currently working on an Invoice App project, and, what I don't really know how to implement it's the following example :

As you know, an invoice must have a unique serial number (or a combination of a Series + Number).

I'm working on a Web API, that supports mostly a CRUD operation. Now, for a POST Method, where should I implement a logic, so that, when a client inserts an Invoice, the number of the invoice gets automatically generated by my app.

My Web API project uses an EF DbContext to get/write data to the DB. Should I implement a Repository, and that repository should take care of Inserting/Reading data?

Upvotes: 0

Views: 1360

Answers (2)

Thomas
Thomas

Reputation: 726

I'll take a stab at answering this as well; it seems you have two concerns here, which might be the same concern, said differently, I may be misunderstanding your question.

  1. Generation of a unique serial number
  2. Incrementation of the invoice number.

Here are some potential options...

Leverage SQL for your auto-incremented numbers...

  • A good architectural style delays decisions; do you want to rely on sql server to generate these for you? If you're okay with never using a different database, then, letting sql generate an auto-incremented number for you should be fine.
  • However, if you're ever wanting to utilize a different datastore, I would err on the side of caution and implement the repository and that can hold the logic to generate a unique serial number for your invoice record. Thus, you decouple the generation of the unique identifier from the datastore.
  • However, I'm not sure that actually fully accomplishes what you're seeking. It seems you need characters and digits, so then the question would be, what is the format it must be in? Are there constraints? For example, all invoices in Mexico are appended with MX-.

Implement the repository

  • Generation of the unique serials and their constraints can be done here; testing is easy with a controller > repository pattern, typically I use Moq. This allows you to get this concern away from the controller when really all you're wanting to do there is accept a POST request, and call _repository.AddInvoice(invoice);.
  • The repository can then handle the rest, based off of your business logic and requirements.

Implement generation of this identifier on the domain object

  • Martin Fowler has this article if you're interested in the plight of anemic domain models. Basically the TL;DR on it is encapsulate the data and behavior thereof on the model itself. This (should) make for easy testing.

Upvotes: 0

mohammadSayadi
mohammadSayadi

Reputation: 31

it would help more if you can supply more information such as how your current model looks like. with current information I see following approach that can help you

assuming this is your invoice model

public class invoice
{
    public int Id { get; set; }
    DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string InvoiceNumber { get; set; }
    //other properties 
}

then in your model builder do as following

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<invoice>()
        .Property(b => b.Created)
        .HasComputedColumnSql("[somepropertyoftable] + ', ' + getdate()");
}  

link below can be helpful:

https://learn.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=data-annotations

Upvotes: 2

Related Questions