Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository Add and Create methods

Why are repositories' .Add method usually implemented as accepting the instance of entity to add, with the .Id already "set" (although it can be set again via reflection), which should be repo's responsibility?
Wouldn't it be better to implement it as .CreateAndAdd?

For example, given a Person entity:

public class Person
{
    public Person(uint id, string name)
    {
        this.Id = id;
        this.Name = name;
    }

    public uint Id { get; }
    public string Name { get; }
}

why are repositories usually implemented as:

public interface IRpository<T>
{
    Task<T> AddAsync(T entity);
}

and not as:

public interface IPersonsRpository
{
    Task<Person> CreateAndAddAsync(string name);
}
like image 639
Sergio Avatar asked Mar 25 '19 17:03

Sergio


People also ask

What is a repository method?

The Repository pattern is used to decouple the business logic and the data access layers in your application. The data access layer typically contains storage specific code and methods to operate on the data to and from the data storage.

What is Repository and unit of work pattern?

The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application.

What is repository in OOP?

Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer.

Why we need Repository pattern in c#?

Repository pattern is one of the preferred patterns to apply in an application because it allows programmers to integrate all of the fundamental data operations related to an entity in one main class. Without this pattern, developers would need to create multiple classes for each entity with the same logic.


1 Answers

why are repositories usually implemented as...?

A few reasons.

Historically, domain-driven-design is heavily influenced by the Eric Evans book that introduced the term. There, Evans proposed that repositories provide collection semantics, providing "the illusion of an in memory collection".

Adding a String, or even a Name, to a collection of Person doesn't make very much sense.

More broadly, figuring out how to reconstitute an entity from a set of a parameters is a separate responsibility from storage, so perhaps it doesn't make sense to go there (note: a repository often ends up with the responsibility of reconstituting an entity from some stored memento, so it isn't completely foreign, but there's usually an extra abstraction, the "Factory", that really does the work.)

Using a generic repository interface often makes sense, as interacting with individual elements of the collection via retrieve/store operations shouldn't require a lot of custom crafting. Repositories can support custom queries for different kinds of entities, so it can be useful to call that out specifically

public interface IPersonRepository : IRepository<Person> {
    // Person specific queries go here
}

Finally, the id... and the truth of it is that identity, as a concept, has a whole lot of "it depends" baked into it. In some cases, it may make sense for the repository to assign an id to an entity -- for instance, using a unique key generated by the database. Often, you'll instead want to have control of the identifier outside of the repository. Horses for courses.

like image 107
VoiceOfUnreason Avatar answered Nov 03 '22 19:11

VoiceOfUnreason