How to respect Clean Code Architecture with mongoDb database?
Asked Answered
B

2

5

I'm setuping a C# Asp.Net Core Api that will grow quite a bit in the future. So I'm trying to respect the Clean Code architecture, with my domain in the center without any dependences and everything around:

public abstract class Entity
{
    public Guid Id { get; set; }
}

I'm currently implementing the repositories. My issue is that for mongoDb, it seems mandatory to either provide the [BsonId] attribute, either use the BsonId in my entities. But that implies adding a mongoDb reference in my entity project, which I'm not a big fan.

public interface IRepository<TDocument> where TDocument : Entity
{
    IQueryable<TDocument> AsQueryable();
    IEnumerable<TDocument> FilterBy(
        Expression<Func<TDocument, bool>> filterExpression);
    IEnumerable<TProjected> FilterBy<TProjected>(
        Expression<Func<TDocument, bool>> filterExpression,
        Expression<Func<TDocument, TProjected>> projectionExpression);
    Task<TDocument> FindOne(Expression<Func<TDocument, bool>> filterExpression);

    Task<TDocument> FindById(Guid id);
    Task InsertOne(TDocument document);
    Task InsertMany(ICollection<TDocument> documents);
    Task ReplaceOne(TDocument document);
    Task DeleteOne(Expression<Func<TDocument, bool>> filterExpression);
    Task DeleteById(Guid id);
    Task DeleteMany(Expression<Func<TDocument, bool>> filterExpression);
}

In the example I found on Clean Architecture, they are mostly using entity framework, which doesn't require absolutely attributes to work.

I could imagine doing another class and using AutoMapper to map between each other, but that seems cumbersome, since I always want to persist everything that are in my business object, and that could lead to some errors.

Isn't there a way to indicate per collection(or even globally) what is the Id in the repository or when saving ?

Burglarious answered 24/3, 2022 at 9:35 Comment(2)
Mongo will automatically detect Id without you being explicit (i.e. convention on the name "Id"). You can also look at "convention packs", etc. which offer an alternative avenue for configuring things without muddying up your entities.Forsook
I think this article will help you hosting.work/aspnet-core-microservice-web-api-crud-mongodbParvati
T
4

You could use the "BsonClassMap":

BsonClassMap.RegisterClassMap<SomeEntity>(cm =>
        {
            cm.AutoMap();
            cm.SetIgnoreExtraElements(true);
            cm.MapIdMember(c => c.Id);
        });

Reference: https://mongodb.github.io/mongo-csharp-driver/2.14/reference/bson/mapping/

Traject answered 3/6, 2022 at 15:47 Comment(0)
C
3

The above solution using static BsonClassMap should allow you to identify your Id member without "polluting" your domain.

BsonClassMap.RegisterClassMap<SomeEntity>(cm =>
    {
        cm.AutoMap();
        cm.SetIgnoreExtraElements(true);
        cm.MapIdMember(c => c.Id);
    });

One word of advice, for your own sanity: as an architect, you'll need to pick and choose which rules you follow religiously, and where it makes sense to make exceptions.

You may find on occasion that a low-risk package reference will make your life considerably easier, whether it be something for data annotations, or a package that gives you Guard clauses or the Specification pattern, etc... I wouldn't be afraid to break the rule or to embrace some anti-patterns when carefully and thoughtfully considered, and you know the reason WHY it is an anti-pattern.

If you were suggesting adding a dependency to something that was not lightweight, I might suggest you never do it. However, there are certain packages that are intentionally compact, and adding them to your Core/Domain project shouldn't bring shame to your family name. :)

Happy coding!

Cimbalom answered 19/9, 2022 at 19:32 Comment(1)
If it was only for me, I would have referenced it directly, but the thing is that within the team and with the consultant that comes and go, it's easy to know they did put the code at the correct place if the required library isn't at the place they shouldn't put the code.Burglarious

© 2022 - 2024 — McMap. All rights reserved.