Seperating Repository and Service Layer

684 Views Asked by At

I am working on an ASP.NET Core Web API project using EF core and would like to add Repository and Service Layers to my application to achieve Separation of Concerns. However, I still can not figure out where to draw the line between the repository layer and service layer.

What I understood from doing some research is that the repository layer is responsible to simple crud operations, such as simple SELECT statements, while the service layer is responsible for business logic and more complex queries.

Now assume that for example I need to query a set of Books written by a certain author and published in a certain year, how should I go about splitting the logic of this query between the the repository and the service layer, assuming I have several entities other than books?

I was thinking of creating a BookService Class where I would create the linq expression

books.Where(b => b.Author == SomeAuthor && b.Year == SomeYear)

and creating a generic Repository Class Repository<T> and a method that accepts a function expression Get<T>(Expression<Func<List<T>, List<T>>>) and use EF core to get the data from the database.

What do you think of my solution? I appreacitate it if you share any better ideas

1

There are 1 best solutions below

2
sina fayazi On

It is all filters that you want to Query the data. It would help you that I believe it is Crud, too, and it's not business logic. It can be nice to inherit your generic Repository Class and implement the IBookRepository interface that can be injected into your business logic class, then create a method in your repository, GetBooksByFilterAsync, and pass your filters to it. Also, you can create a model BookFilter to pass the data to your repository. and then create an extension method like this

public static IQueryable<Book> ApplyFilter(this IQueryable<Book> query, BookFilter filter)
{
// Filter by Author
            if (!string.IsNullOrEmpty(filter.Author))
                query = query.Where(x => x.Author.ToUpper().Contains(filter.Author.ToUpper()));

            // Filter by Year
            if (filter.Year.HasValue)
                query = query.Where(x => x.Year == filter.Year.Value);
.
.
.
}

And then apply the filter to your IQueryable in your repository.