Type is only generic by containment
Interceptors cannot handle types that involve generic type parameters (see DAP016), and one way to involve them is easy to do by accident: declaring an otherwise generic-free type inside a generic class. For example:
public class AnimalTests<TProvider>
{
class Dog // this actually means AnimalTests<TProvider>.Dog
{
public int Age { get; set; }
public string? Name { get; set; }
}
public void GetDogs(DbConnection connection)
=> connection.Query<Dog>("select Age, Name from Dogs"); // DAP051
}
Here Dog does not use TProvider at all - but because it is declared inside
AnimalTests<TProvider>, its full identity is AnimalTests<TProvider>.Dog, which is a
different type for every TProvider. Generated code cannot name such a type, so Dapper.AOT
has to leave the call-site on vanilla Dapper (reflection), which will not work under AOT.
The fix: if the type does not need the enclosing type parameters, move it out of the generic type - to namespace scope, or into a non-generic containing class:
class Dog // no longer entangled with TProvider
{
public int Age { get; set; }
public string? Name { get; set; }
}
public class AnimalTests<TProvider>
{
public void GetDogs(DbConnection connection)
=> connection.Query<Dog>("select Age, Name from Dogs"); // works with Dapper.AOT
}
If the type genuinely needs the enclosing type parameters, this is the same limitation as DAP016: generic types cannot currently be used with Dapper.AOT.