Let's say I have a data model consisting of 2 classes, both implementing the same interface:
interface IEntity { }
class EntityTypeA : IEntity { }
class EntityTypeB : IEntity { }
I have a generic service which contains a list of these entities and does something with them. There are multiple different implementations of the Service, all inheriting from IService, but let's say for now there's just one, "Service".
interface IService<T> where T : class, IEntity {
// stuff
T GetEntity(Func<T, bool> linq);
}
class Service<T> : IService<T> where T : class, IEntity {
// stuff
IEnumerable<T> _entities;
}
At this point I can easily create new services for various entities and work with them. Add new entities of a specific type to them, call methods, get them back without having to cast anything manually.
IService<EntityTypeA> serviceA = new Service<EntityTypeA>();
IService<EntityTypeB> serviceB = new Service<EntityTypeB>();
All fine, but now I want to have all these services stored in one place so I can easily fetch the one I want later, without having to keep them all in a separate variable.
Ultimately I wanted to be able to do sth like this:
_manager = new ServiceManager();
_manager.AddService("A", serviceA);
_manager.AddService("B", serviceB);
IService<EntityTypeA> serviceA = _manager.GetService<EntityTypeA>("A");
So I tried something like this:
class ServiceManager {
IDictionary<string, IService<IEntity>> _services;
public void AddService<T>(string key, IService<T> manager) where T : class, IEntity {
_services[key] = (IService<IEntity>)manager;
}
public IService<T> GetService<T>(string key) where T : class, IEntity {
return (IService<T>)_services[key];
}
}
The issue here is the "invalid cast exception" when calling the AddService (and probably GetService as well) methods, I cannot cast and store an Service<EntityTypeA>
into IService<IEntity>
. Which was a bit of a surprise to me, since EntityTypeA implements IEntity and Service implements IService...
So my question is: How can I store all these generic services in a single variable so I can easily get them with one method from the manager? I'd like this manager to be a single instance responsible for managing all these services but I have no idea how to hold all these generic classes in it.