C
C#4d ago
KevS

Generic IH Handlers?

I have a json polymorphic type and I depending on where I'm using it, I want to get a different result type. I have two implementations, the top one works but the bottom one seems cleaner but doesn't work. Are generic handlers possible or do I need to stick to method A here
// THIS ONE WORKS
[Handler]
[AutoConstructor]
public sealed partial class LoadPolymorphObject
{
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;

public sealed record Request(int pk, Type targetType);

private async ValueTask<TObject> HandleAsync(Request request, CancellationToken ct)
{
ApplicationDbContext db = await _dbContextFactory.CreateDbContextAsync(ct);

ObjectBase? obj = await db.Table.FindAsync(
request.pk,
cancellationToken: ct
);

return obj.GetType() == request.targetType
? obj
: throw new InvalidCastException();
}
}


// THIS ONE DOESNT
[Handler]
[AutoConstructor]
public sealed partial class LoadPolymorphObject(ApplicationDbContext db)
{
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
public sealed record Request(int pk);

private async ValueTask<TObject> HandleAsync<TObject>(Request request, CancellationToken ct) where TObject : ObjectBase
{
ApplicationDbContext db = await _dbContextFactory.CreateDbContextAsync(ct);

FoundObject? obj = await db.Table.FindAsync(request.pk, cancellationToken: ct
);

return obj is TObject ? obj : throw new InvalidCastException();
}
}
// THIS ONE WORKS
[Handler]
[AutoConstructor]
public sealed partial class LoadPolymorphObject
{
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;

public sealed record Request(int pk, Type targetType);

private async ValueTask<TObject> HandleAsync(Request request, CancellationToken ct)
{
ApplicationDbContext db = await _dbContextFactory.CreateDbContextAsync(ct);

ObjectBase? obj = await db.Table.FindAsync(
request.pk,
cancellationToken: ct
);

return obj.GetType() == request.targetType
? obj
: throw new InvalidCastException();
}
}


// THIS ONE DOESNT
[Handler]
[AutoConstructor]
public sealed partial class LoadPolymorphObject(ApplicationDbContext db)
{
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
public sealed record Request(int pk);

private async ValueTask<TObject> HandleAsync<TObject>(Request request, CancellationToken ct) where TObject : ObjectBase
{
ApplicationDbContext db = await _dbContextFactory.CreateDbContextAsync(ct);

FoundObject? obj = await db.Table.FindAsync(request.pk, cancellationToken: ct
);

return obj is TObject ? obj : throw new InvalidCastException();
}
}
8 Replies
Angius
Angius4d ago
GitHub
Support for generic handlers · Issue #59 · ImmediatePlatform/Imme...
Given a structure that looks something like this public abstract record Message { } public record SomeMessage : Message { } public record OtherMessage : Message { } There is currently no way of han...
Angius
Angius4d ago
And gonna CC @viceroypenguin right quick as well
viceroypenguin
didn't we end up deciding that generic handlers weren't going to be as useful as we thought? i haven't even explored it since our conversation
Angius
Angius4d ago
I'm honestly not sure tbh. I think I eventually did move away from needing a generic handler... somehow Been a while
viceroypenguin
huh, you didn't open that ticket, and the guy who did isn't on the server anymore iirc, there was some difficulty in dealing with the call-tree through behaviors and such because now it's harder to validate what types are possible in behaviors, etc.
KevS
KevSOP4d ago
I will admit its a pretty niche use case. What I'm doing right now does work so its nbd I just thought I should bring it up
viceroypenguin
yeah, it's a known corner case, but doesn't seem to be a big enough problem to justify the work involved in addressing it
KevS
KevSOP4d ago
Totally fair.

Did you find this page helpful?