Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscribing a runtime type #11

Closed
odannyc opened this issue Apr 24, 2018 · 5 comments
Closed

Subscribing a runtime type #11

odannyc opened this issue Apr 24, 2018 · 5 comments
Assignees
Labels

Comments

@odannyc
Copy link

odannyc commented Apr 24, 2018

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:

Type t = typeof(Foo);
_messageHub.Subscribe<t>({Some method})

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:

Type t = typeof(Foo);
_messageHub.Subscribe(t, {Some method})
@NimaAra NimaAra self-assigned this Apr 24, 2018
@NimaAra
Copy link
Owner

NimaAra commented Apr 24, 2018

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}"));

@NimaAra NimaAra closed this as completed Apr 24, 2018
@odannyc
Copy link
Author

odannyc commented Apr 24, 2018

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);
}

@NimaAra
Copy link
Owner

NimaAra commented Apr 24, 2018

It does work, RegisterGlobalHandler receives every message published. You will have the type as well as the payload.

@odannyc
Copy link
Author

odannyc commented Apr 24, 2018

Okay, just tested and it works just for one Type.. I have multiple Types ... 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?

@NimaAra
Copy link
Owner

NimaAra commented Apr 24, 2018

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
    }
    ...
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants