BACKGROUND: We've an ASP.NET Core based web app using EF Core developed on top of DI & Generic Repository pattern. So, most of the things are done using interfaces. Now, we've reached master table maintenance module. We don't want to replicate the same service (backed by repository) class for all 10-20 master tables.
So, we've created a _ModelMasterBase
class and derived all the master table classes from it. The CRUD for all master tables is the same. So, next we implemented things like MasterRepository<T>
, MasterService<T>
and their interfaces. Now everything has to use <T>
where T
is the type of the master table selected on the page to perform CRUD.
Initially, I expected that instance of IMasterService<_ModelMasterBase>
can be converted to IMasterService<T>
- again where T
could be any child class derived from _ModelMasterBase
- But it seems impossible! I've tried operators, casting, and almost everything I could google! Also due to repository pattern everything has to be strongly typed.
Now, we already use the trick to convert child obj to base class obj as per SO Post -
DerivedClass B = new DerivedClass();
BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));
I know its a bit dirty trick but sometimes its handy to maintain the tradeoff between design and complexity. We use it with precaution. I wish there was something similar in case I wanted to cast MyService<Base>
to MyService<Child>
Or you can forget all this and guide me to have a single point CRUD service for all my master tables - replicating the same thing 10-20 times seems irrational. Sorry, I couldn't explain in depth as it'd stretch the post.
Here's a v.basic sample of my code structure and at the end you'll see what we're trying to achieve. Hope it helps.
SOLUTION :
Based on mkArtak's suggestion, I was able to crack it by using 'Covariance' concept (example). Here's my updated code sample. Now there's a single controller and service layer for all master tables!