I have the following interface:
public interface INotificationHandler<T>
{
Task<T> Handle(string msg);
}
And several classes that happily implement it like so:
public class FooHandler : INotificationHandler<Foo>
{
public Task<Foo> Handle(string msg) { return Task.FromResult<Foo>(new Foo()); }
}
public class BarHandler : INotificationHandler<Bar>
{
public Task<Bar> Handle(string msg) { return Task.FromResult<Bar>(new Bar()); }
}
I'd like to keep a collection of INotificationHandler instances in a collection and when I get a message "foo", use the FooHandler, "bar" gets the BarHandler, etc...
var notificationHandlers = new Dictionary<string, INotificationHandler<object>>();
notificationHandlers["foo"] = new FooHandler();
notificationHandlers["bar"] = new BarHandler();
...
public void MessageReceived(string type, string msg)
{
INotificationHandler<object> handler = notificationHandlers[type];
handler.Notify(msg).ContinueWith((result) => /* do stuff with a plain object */)
}
However this fails to compile because my generic has no common base type, which is by design. Any object should be able to be returned from a INotificationHandler in MessageReceived
.
Cannot implicitly convert type
FooHandler
toINotificationHandler<object>
. An explicit conversion exists (are you missing a cast?)
How can I work with INotificationHandler<T>
so that I don't need care about the generic types of its concrete implementations?
If you need a type safety you can use the following hierarchy.
public interface INotificationHandler
{
Task<object> Handle(string msg);
}
public abstract BaseHandler<T> : INotificationHandler
{
Task<object> INotificationHandler.Handle(string msg)
{
return Handle(msg);
}
public abstract Task<T> Handle(string msg);
}
public class FooHandler : BaseHandler<Foo>
{
public override Task<Foo> Handle(string msg) { return Task.FromResult<Foo>(new Foo()); }
}
public class BarHandler : BaseHandler<Bar>
{
public override Task<Bar> Handle(string msg) { return Task.FromResult<Bar>(new Bar()); }
}
var notificationHandlers = new Dictionary<string, INotificationHandler>();
notificationHandlers["foo"] = new FooHandler();
notificationHandlers["bar"] = new BarHandler();
...
public void MessageReceived(string type, string msg)
{
INotificationHandler handler = notificationHandlers[type];
handler.Notify(msg).ContinueWith((result) => /* do stuff with a plain object */)
}
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