I’m working on a framework which builds on .net core Identity. Let’s say I wanted to extend the IdentityUser<TKey>
class with a ParentUserId
property while the developer should still be able to decide which type to use for the TKey
primary key. This property would be a foreign key to another user, but could be null
if the user doesn’t have a parent.
Using string
for TKey
would work without problems because strings are nullable and don’t conflict with the where TKey : IEquatable<TKey>
constraint (although I don’t know why). But if the developer decides to use int
, I’m screwed.
Currently I’m thinking about a solution like this:
public class FrameworkUser<TKey, TNullableKey> : IdentityUser<TKey> where TKey : IEquatable<TKey> { public virtual TNullableKey ParentUserId { get; set; } // for better understanding public virtual FrameworkUser<TKey, TNullableKey> ParentUser { get; set; } }
But I’m very unsure and don’t think it’s beautiful.
-
The developer could do something like
new FrameworkUser<string, int?>()
by mistake. Would be great if something likewhere TNullableKey : Nullable<TKey>
were possible. -
I can’t constraint
TNullableKey
.IEquatable
doesn’t allow nullable value types (i.e.int?
), although I don’t know if this will result in worse performance when used as a foreign key anyway.struct
won’t allow strings. -
Getting the value of
ParentUserId
will differ depending on the type. For instance to securely get the value of anint?
, I would check forint?.HasValue
to betrue
and then get it’s value fromint?.Value
. The same procedure is quite different for astring
which could benull
, empty, or have some chars. This would make switches from one type to another without extra work difficult/impossible.
Another solution could be having two implementations, one for string
and one for struct
, but that’s not feasible because then I would also need to have two IdentityStore<TUser>
s and so on.
So, what would you do?