Code Monkey home page Code Monkey logo

inheritanceissuedemo's Introduction

Inheritance Issue Demo

Context

In some of my recent projects, I have modeled my domain layer following the design of that used in Amichai Mantinband's Buber Dinner course. To get the base models to work with EF Core, the AggregateRoot<TId, TIdType> class defines a new Id property of type AggregateRootId<TId> which hides the base Entity<TId>.Id property which is generically typed TId. While this solves the issue with EF Core, it introduces a new issue related to reflection.

When using instances derived from AggregateRoot<TId, TIdType> with certain libraries, such as Radzen Blazor Components and Mapster, a NullReferenceException is thrown because they are invoking Entity<TId>.GetHashCode() which in turn invokes the GetHashCode() method on Entity<TId>.Id. However, Entity<TId>.Id is never set.

image

The Issue

The primary issue is that I don't really understand why Entity<TId>.Id is being referenced. I understand that the override of GetHashCode() is implemented in Entity<TId>, but the runtime should know that the underlying type of the object is AggregateRoot<TId, TIdType>, which hides the base Id property. I don't understand why the appropriate property is not being referenced. I could also define the GetHashCode() and other methods in the AggregateRoot<TId, TIdType> class, but that would defeat the entire purpose of inheriting from Entity<TId>.

I also fail to understand an issue related to one of the solutions. The solution being to modify the constructor of AggregateRoot<TId, TIdType> so that is passes the value down to the base constructor. As I'll explain in the next section, I was actually able to successfully solve this issue with this solution in this demo. However, when I tried this in one of my more complex projects, the value of the underlying Entity<TId>.Id property was still null at runtime. I am currently trying to figure out why it's not working in my other project and attempt to reproduce in this demo.

Solutions

1 | branch ResolveWithDtoAndGuid

My first solution is to create DTOs which use the underlying type for the aggregate ids. If all I was doing was creating an API to expose publicly, this would be fine. However, since I am using these types in the presentation layers (e.g., Blazor, MAUI, etc.), using DTOs for this reason defeats the purpose of using strongly typed ids.

2 | branch PassIdToBaseCtor

Update the constructor for AggregateRoot<TId, TIdType> so that it passes the value down to the base constructor as well.

protected AggregateRoot(TId id)
    : base(id) =>
    Id = id;

While this does appear to resolve the issue in this demo project, I have not been so lucky with one of my more complex projects. I will update soon with more information. To try and reproduce this solution not working, I will also be testing this with the Mapster library as well as EF Core. What I suspect is happening is that, because EF Core doesn't use the constructor, it only sets AggregateRoot<TId, TIdType>.Id when loading the entities from the database, thus leaving Entity<TId>.Id set to null.

inheritanceissuedemo's People

Contributors

justinianerdmier avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.