.NET Client - AndersMalmgren/SignalR.EventAggregatorProxy GitHub Wiki

Dot Net Core

The .NET client have seen alot of breaking changes and improvements with Dot Net Core

Install the Core client using (Its netstandard 2.0 so works with Framework 4.x too). remark: Core 3.0 version uses netstandard 2.1 which is not working with full framework

Install-Package SignalR.EventAggregatorProxy.Client.DotNetCore

Event aggregator

The .NET client has a built in event aggregator that you can use. We have also improved the pipeline for configuring it.

serviceProvider = new ServiceCollection()
    .AddSignalREventAggregator()
    .WithHubUrl("http://localhost:60976/EventAggregatorProxyHub")
    .OnConnectionError(e => Debug.WriteLine(e.Message))
    .Build()

There are some callback methods that you can call to listen to specific protocol state changes.

serviceProvider = new ServiceCollection()
    .AddSignalREventAggregator()
    .WithHubUrl("http://localhost:60976/EventAggregatorProxyHub")
    .OnConnectionError(...)
    .OnSubscriptionError(...)
    .OnConnected(...)
    .Build() 

IEventTypefinder

We no longer use a Base event to find out which events are proxied. Instead implement IEventTypefinder and register it with the DI.

serviceProvider = new ServiceCollection()
    .AddSignalREventAggregator()
    .WithHubUrl("http://localhost:60976/EventAggregatorProxyHub")
    .Build()
    .AddSingleton<IEventTypeFinder, EventTypeFinder>()

Both your backend and client should share the same Assembly containing the events. This way you ensure that the fully qualified name is same in both cases.

IoC (Dependency Injection)

AddSignalREventAggregator Hooks up the dependency to the IProxyEventAggregator

There is also a version of it with client side only methods. Make sure they point to the same reference, the Dot Net Core DI does not support this out of the box, you can do

serviceProvider = new ServiceCollection()
    .AddSignalREventAggregator()
    .WithHubUrl("http://localhost:60976/EventAggregatorProxyHub")
    .Build()
    .AddSingleton<IEventAggregator>(p => p.GetService<IProxyEventAggregator>())

Global and local Event aggregators

The event aggregator injected by AddSignalREventAggregator is configured like a singleton. But you can also subscribe and publish client side only events. If you use the global singleton event aggregator all Models, services etc in the Application will receive the event. This is not always desired you can then register a Child IoC on a Window level or other level of your choice. If you do this make sure you register the IEventAggregator interface for the local scope, otherwise they will conflict. You can then use IProxyEventAggregator for global scope and IEventAggregator for local scope.

Subscribe to events

The class that is a listener to a event must implement IHandle and also call subscribe on the Event aggregator like.

public class MyViewModel : IHandle<MyEvent>
{
   public MyViewModel(IEventAggregator eventAggregator) 
   {
      eventAggregator.Subscribe(this);
   }
   public void Handle(MyEvent message)
   {
      //Act on MyEvent
   }
}

You can have multiple IHandle<> interfaces on a class.

Add constraints

As covered Here you can have constraints so that a client only receives a selection of a event. To hook up a constraint you have to change the subscription part a bit.

public MyViewModel(IProxyEventAggregator eventAggregator) 
{
   eventAggregator.Subscribe(this, builder => builder.For<MyEvent>().Add(new MyEventConstraint{ Id = 100 }));
}

This overload of Subscribe is only available on the IProxyEventAggregator

Publish

You can publish client side only events like

eventAggregator.Publish(new ClientSideEvent());

Event proxy

Maybe you have a existing event aggregator in your client, if this is the case you need to proxy between our SignalR proxy and your event aggregator. Use the EventProxy class for this. To see how it works check out the Source here at github.

SignalR 2.x (Deprecated)

Install the .NET client using

Install-Package SignalR.EventAggregatorProxy.Client.DotNet

Latest version of client requires SignalR.EventAggregatorProxy.1.4.117 or later

Event aggregator

The .NET client has a built in event aggregator that you can use.

   eventAggregator = new EventAggregator<EventBase>()
      .Init("http://localhost");   

The generic argument is the base class for all your events, both your backend and client should share the same Assembly containing the events. This way you ensure that the fully qualified name is same in both cases.

Init

We choose to have a empty constructor for the EventAggregator because that way you can dependency inject the event aggregator. Instead you call Init on the instance to setup the URL for the hub. The init method also takes a delegate where you can add additional settings to the connection. For example to configure Windows authentication. Only call Init once.

eventAggregator = new EventAggregator<EventBase>()
   .Init("http://localhost", c => c.Credentials = CredentialCache.DefaultCredentials);

There are some callback methods that you can call to listen to specific protocol state changes.

   eventAggregator = new EventAggregator<EventBase>()
      .OnConnected(() => Console.WriteLine("Connected"))
      .OnConnectionError(e => Console.WriteLine(e.Message))
      .OnSubscriptionError((e, s) => Console.WriteLine(e.Message))
      .Init("http://localhost");   

IoC (Dependency Injection)

The best way of ensuring that the aggregator is just instanced once is to use a IoC and configure its lifetime management to be Singleton. With Ninject it would look like this.

kernel.Bind<IEventAggregator<BaseEvent>>().To<EventAggregator<BaseEvent>>().InSingletonScope();

You can also register it without the generic interface like

kernel.Bind<IEventAggregator>().To<EventAggregator<BaseEvent>>().InSingletonScope();

Global and local Event aggregators

The event aggregator containing the hub proxy should always be configured like a singleton. But you can also subscribe and publish client side only events. If you use the global singleton event aggregator all Models, services etc in the Application will receive the event. This is not always desired you can then register a Child IoC on a Window level or other level of your choice. If you do this make sure you register the generic interface for the global scope. And the none generic interface for the local scope, otherwise they will conflict.

Subscribe to events

The class that is a listener to a event must implement IHandle and also call subscribe on the Event aggregator like.

public class MyViewModel : IHandle<MyEvent>
{
   public MyViewModel(IEventAggregator eventAggregator) 
   {
      eventAggregator.Subscribe(this);
   }
   public void Handle(MyEvent message)
   {
      //Act on MyEvent
   }
}

You can have multiple IHandle<> interfaces on a class.

Add constraints

As covered Here you can have constraints so that a client only receives a selection of a event. To hook up a constraint you have to change the subscription part a bit.

public MyViewModel(IEventAggregator<EventBase> eventAggregator) 
{
   eventAggregator.Subscribe(this, new[] { new ConstraintInfo<MyEvent, MyEventConstraint>{ Id = 100 } });
}

This overload of Subscribe is only available on the generic version of the IEventAggregator

Publish

You can publish client side only events like

eventAggregator.Publish(new ClientSideEvent());

Event proxy

Maybe you have a existing event aggregator in your client, if this is the case you need to proxy between our SignalR proxy and your event aggregator. Use the EventProxy class for this. To see how it works check out the Source here at github.

⚠️ **GitHub.com Fallback** ⚠️