I have the following interface
public interface IHandler<T>
{
void Handle(T myObject);
}
I'd like to have a HandlersManager
class with holds a mapping between object types to their corresponding handler, but I'm not sure how I'm supposed to define the object that hold this mapping.
For example, what I'd like to have is this:
typeof(string) --> instance of IHandler<string>
typeof(MyClass) --> instance of IHandler<MyClass>
The best thing I got so far was to define Dictionary<Type, object>
for the mapping, but in this case I would have to cast the value to IHandler<T>
every time I get it.
Is there a better solution or something that I have completely missed?
I suspect you're using this to resolve dependencies. Instead, use a dedicated container that will handle these issues for you.
If you don't want to do that, you want something like this:
Dictionary<Type, object> dictionary;
IHandler<T> Resolve<T>() {
return (IHandler<T>)dictionary[typeof(T)];
}
There isn't any other way with generics.
Is there a better solution or something that I have completely missed?
No, but manager classes are generally code smells. Be careful.
That's as good as it can get with only a generic IHandler<T>
interface.
In order to explore more options, we could define a non-generic version of the interface:
public interface IHandler
{
void Handler(object myObject);
}
Then you could also define a generic abstract base class that implements both IHandler<T>
and IHandler
:
public abstract class BaseHandler<T> : IHandler, IHandler<T>
{
public abstract void Handle(T myObject);
void IHandler.Handle(object myObject)
{
((IHandler<T>)this).Handle((T) myObject);
}
}
At this point you can have an IDictionary<Type, IHandler>
and you can directly call IHandler.Handle
on the values you pull out of it:
var obj = /* whatever */
dictionary[obj.GetType()].Handle(obj);
On the other hand we now have an additional interface and an abstract base class just to hide a cast from "user" code, which doesn't sound very impressive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With