Cassandra.Mapping.Map.GetPropertyOrField() failing if memberExpression.Member.DeclaringType is an interface
Description
Environment
Activity
Uwe Mayer March 8, 2023 at 9:00 PM
Thanks for the help anyway. I will find a temporary solution meanwhile.
Joao Reis March 8, 2023 at 4:44 PM
I’ve seen some users use abstract classes for this which work fine with the mapper but for your use case interfaces probably make more sense and I agree this would be an easy fix regardless.
We are not planning a driver release in the next couple of months so I would recommend using abstract classes as a workaround for now if possible.
Uwe Mayer March 8, 2023 at 3:44 PM(edited)
We use this abstraction for a generic repository provider library. This gives us freedom for the class design later in our applications. And in this particular case, the key is declared in an interface.
If others may need this once, I cannot say, but I know a lot of cases where composition rules over inheritance…
As far as I can tell, the proposed solution is very simple and should not have a negative side effect on the driver.
Joao Reis March 8, 2023 at 2:54 PM
Is there a valid use case for someone to use interfaces with the mapper instead of classes?
Problem:
The PartitionKey and Column functions of the mapping fail under certain circumstances when Cassandra.Mapping.Map.GetPropertyOrField() has to detect, that the declaring type is an interface that is implemented by the POCO type.
Steps to reproduce:
Take the linq-sharp example code and create an interface IUser exposing the UserId like declared in User. Then let User implement IUser. Finally, create the following method in Program.cs and call it instead of directly calling the Mapper:
private void MapUser<T>() where T : IUser { MappingConfiguration.Global.Define( new Map<T>() .TableName("users") .PartitionKey(u => u.UserId) .Column(u => u.UserId, cm => cm.WithName("id"))); }
This will fail.
Solution:
In Cassandra.Mapping.Map.GetPropertyOrField() use "memberExpression.Member.DeclaringType.IsAssignableFrom(_pocoType)" instead of "_pocoType.GetTypeInfo().IsSubclassOf(memberExpression.Member.DeclaringType)". Also refer to the remarks section in https://learn.microsoft.com/en-us/dotnet/api/system.type.issubclassof?view=net-7.0.