Converting from a string to a generic method invocation
Looking for design patterns to help solve this problem I’m having at work. The situation is that we have a URL like GET /entities/<userid>/<entity type> where entity type is a string, and we want to fetch the entities of that type belonging to the current user.
Normally I would just use a switch case to go from eg entitytype = “someentity” => entitiesService.GetEntities<SomeEntity>(). But my tech lead insists that new entity types should be automatically supported without code changes to this endpoint because he thinks it will be forgotten.
I’ve landed on a solution using reflection to grab the types deriving from my base Entity class and build a dict of (string, Type), then using reflection to get the method info of GetEntities and use MakeGenericMethod with the type from the dict, but am not too pleased with it.
I’m considering the following alternatives:
- source generators, seemed like a lot of code to generate 1 switch case
- using reflection in the testing to make the pipeline fail if another dev forgets to update the endpoint
But I’d like to know if there are any other solutions people can think of / thoughts on some of the existing options
5 Replies
One question, do you use ef core?
cause i recently had to change the efcore code to dapper queries as dynamic Entities are not supported. if its a local c# entity then all good
Yeah we use ef core
But I’m using .Set<TEntity> to accomplish the generic ness
so it's a table per type situation?
Yeah
Kinda leaning towards a Dictionary<string, Func<…> that I just manually define
And then an automated test that uses reflection
its a simple approach where you dont use switch case 😄
switch statement needs compiled value and not a generated one. you can use and enum. I have used it before and it works well.
sharing one sample enum which maps to strings.
Obtained from an article by Steve (you might know him from Ardalis Endpoints)
then you use if else statements, along with LookupEnum.FromString(entity) and you can also put validations if the mapping fails