0

I am currently working on implementing the Clean Architecture pattern using Entity Framework. However, I've encountered an issue related to the design of my Domain project. In this project, I need to define a "Wallets" table that should have a relationship with the "User" entity from the Identity project. Additionally, the "User" entity also needs to be aware of its associated "Wallets." It's important to note that a single user can have multiple wallets, while each wallet can only belong to one user. Now, I'm uncertain about the best approach to avoid this circular dependency and where I might have made a mistake in my architecture. Any advice or insights on how to resolve this situation would be greatly appreciated.

I have tried adding some interfaces, but I ran into another issue "he property 'Wallet.User' is of an interface type ('IApplicationUser'). If it is a navigation, manually configure the relationship for this property by casting it to a mapped entity type. Otherwise, ignore the property using the [NotMapped] attribute or 'Ignore' in 'OnModelCreating'"

12
  • 1
    For identity purposes, why does a user need to know it's wallets? Commented Jul 23, 2023 at 14:34
  • Wallet belongs to the user, each user can have multiple wallets. I am confused with this approach, because I have 2 Context, and each time I need to connect something with Identity, I'm facing issues
    – pakerinjo
    Commented Jul 23, 2023 at 14:46
  • 1
    Can you edit your question to include more information about how the user entity is used in the domain library, what it is used for in the identity library, and why a user needs to know its wallets in both cases? My intuition says you are missing an entity, but it is hard to tell from the limited information in this question. Commented Jul 23, 2023 at 14:48
  • 1
    “ User needs to know about wallet, because each user can have list of wallets. ” that’s not what that means. Given a user you need a list of their wallets. That doesn’t at all mean the user type even knows that wallets exist. Or that wallets know that users exist. Having a “relationship” does not require a source code dependency. Needing one to be able to call the other does. Commented Jul 23, 2023 at 15:12
  • 2
    You bringing up tables (and code first, for that matter) should have nothing to do with a discussion on how you design your domain. This is the first hint that something's gone wrong in your understanding of what the domain represents and therefore how it should be designed. You need to go back to the drawing board on your understanding of clean architecture. Any answer given here will only be a patch to fix your current issue but not your overall design.
    – Flater
    Commented Jul 23, 2023 at 17:30

2 Answers 2

1

Part of your problem comes from the fact that you are confusing (and trying to merge) two different entities that happen to have very similar names.

  • Identity.User: The class with information about the person who provided his/her credentials and currently uses the application
  • Domain.User: The user that the domain experts talk about and who owns a number of Wallets.

The fact that both are called User is not helping in keeping them apart, but they should be kept apart as they represent different ideas. Take for example the use case where I authorize you to perform actions on my Wallets. They would log in with their own credentials (Identity.User == pakerinjo), but they need to access my Wallets (Domain.User == BartvanIngenSchenau).

4
  • In that case, I need to create Domain User, and still need to connect it with the Identity User, which is pretty much the same as with the wallet
    – pakerinjo
    Commented Jul 24, 2023 at 15:21
  • @pakerinjo, there is no need to connect Domain.User and Identity.User. They can exist independently. Commented Jul 24, 2023 at 16:26
  • But how will I know, when the Identity.User logs in, who is the corresponding Domain user? Also what characteristic has the Domain user, that Identity.User doesn't?
    – pakerinjo
    Commented Jul 24, 2023 at 16:42
  • 1
    The identity user would have a claim that contains the domain user ID. The domain application can then look up the user (by inspecting the authentication token for its claims). store the domain user ID in session, and use it for the database calls. The domain application should not know about the identity user table, just the claim and ID.
    – John Wu
    Commented Jul 25, 2023 at 22:20
0

It sounds like you have two different contexts here: User(s) and Wallet(s), I am going to assume you are using a surrogate key (such as a GUID) to identify each entity (UserId and WalletId).

I think the crux of your issue is how you are "connecting" the two contexts together, specifically you are trying to use the full objects instead of just the IDs.

If the Users and Wallets were implemented inside two different services:

  • There would be no need for the Users service to have any reference to the Wallets (it's a different context).
  • The Wallet service only needs the UserId to look up the attached Wallets.

Depending upon your preference for type safety you could either just use a GUID type (to represent the UserId in the Wallet service) or wrap each of the GUIDs in small reference classes (i.e.: UserId) - if you encounter circular dependencies, because of these reference types you can simply move all of them to a "references" package so that the main services don't create circular dependencies.

1
  • Yes, you are right. I have 2 separate contexts, and there is no way of connecting them with full objects, I just used Id instead. I don't think I made any mistake with this approach, I was just confused. Now domain model has a wallet with userId as a property, and the identity user, has list of wallets as full objects, and it can work fine
    – pakerinjo
    Commented Jul 24, 2023 at 17:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.