Closed odannyc closed 6 years ago
I intend to keep the interface generic to avoid boxing but you can use the GlobalHandler in your specific case:
hub.RegisterGlobalHandler((type, eventObject) => Console.WriteLine($"Type: {type} - Event: {eventObject}"));
This won't work because the event object is not known until the Publish
phase.
I looked through the code and saw some ways to do it. Can we do this:
Make the Register method:
internal static Guid Register(TimeSpan throttleBy, Action<object> action, Type type)
{
var key = Guid.NewGuid();
var subscription = new Subscription(type, key, throttleBy, action);
lock (AllSubscriptions)
{
AllSubscriptions.Add(subscription);
_subscriptionsChangeCounter++;
}
return key;
}
These would now be the Subscribe
overloads:
public Guid Subscribe<T>(Action<T> action) => Subscribe(action, TimeSpan.Zero, typeof(T));
public Guid Subscribe<T>(Action<T> action, TimeSpan throttleBy) => Subscribe(action, throttleBy, typeof(T));
public Guid Subscribe(Action<object> action, TimeSpan throttleBy, Type type)
{
EnsureNotNull(action);
return Subscriptions.Register(throttleBy, action, type);
}
It does work, RegisterGlobalHandler receives every message published. You will have the type as well as the payload.
Okay, just tested and it works just for one Type
.. I have multiple Type
s ... So this won't work with my use case.
This is my test code:
_hub.RegisterGlobalHandler((type, eventObject) =>
{
if (type == externalType)
{
listener.Handle(eventObject);
}
});
Each time RegisterGlobalHandler
is called, it overrides the last one.
Any other way to accomplish this? What do you think of my suggestion above?
It does work, I am not going to change the interface (add or remove).
The purpose of RegisterGlobalHandler is to register 1 single handler which will receive every message of every type passed through the hub. It is not meant to build up multiple handlers.
In your case you can compose a handler which knows how to behave based on the types that you are interested in at run-time then register that as the global handler.
_hub.RegisterGlobalHandler((type, eventObject) =>
{
if (type == firstType)
{
// handle eventObj
}
else if (type == secondType)
{
// handle eventObj
}
...
});
I need to subscribe a runtime type which is defined with an attribute. For example: I have class Foo, which I want to subscribe to an Action (non-generic) That class Foo is defined by an attribute at runtime, meaning I can't do this:
I know this isn't valid syntax so this won't work. Is there anyway to make this work? I was thinking something like this, but not sure if it'll work: