Lets say i have a zoo
class, with a bunch of collections. The collections are giraffes
, elephants
, tigers
etc. All animal types derive from the same interface or base class, lets call it IAnimal
.
So in my code i'm running in the same problem in 2 places. I end up in a method, that gets an IAnimal that its supposed to delete, but i dont know which exact type it is. So i basically end up with methods that look like this
if(animal is Tiger tiger)
Zoo.Tigers.Remove(tiger);
TigerRepository.Delete(tiger);
else if(animal is Giraffe giraffe)
Zoo.Giraffes.Remove(giraffe);
GiraffeRepository.Delete(giraffe);
....
This code moves around, sometimes it lands in the zoo class, sometimes in a DBService class, sometimes in a viewmodel. Sometimes its a dictionary, but lets be honest its the same thing.
I know i can probably brute force a solution that i never need to touch again with some smart reflection somehow, but that feels like its not really OOP.
I can split up the method it ends up in from a single method that gets an IAnimal
into several method that get a Tiger
, Giraffe
etc, but that feels the same as a big factory method. It feels like i should be able to do something with generics, but it just doesn't work since i don't know the type at compile time.
The best i can do is a bunch of DeleteTiger(Tiger tiger)
methods that internally call a DeleteAnimal<Tiger>
method that saves a single line of code in each of the delete methods.
This isn't just a theoretical best practice thing, i keep having to go back and back to that method every time i add a new subentity to my application.
What can i do to stop having to do this? Can i even do anything?
Edit: I don't like the just make an animal collection approach, but it would definitely work with in memory objects. I would never get the idea to model a zoo as "300 animals", its 20 monkeys, 5 tigers... etc.
However how would this approach work with the repositories or entity frameworks dbsets WITHOUT having a method that just switches on the type again takes that repository / dbset and calls the Delete method?
I just saw that EF Cores DBContext actually has just simple Remove(object entity) method, but internally it probably just type checks too. I feel like i cant get around it with a repository pattern approach.