'global object that needs to be referenced in a message handler

I have a signalr client that I want to be global.

I think creating the signalr client in the Init() of the endpointconfig would be best.

public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
    public static HubConnection hubConnection;
    public static IHubProxy hubProxy;

    public void Init()
    {
        Configure.With()
            .DefiningEventsAs(t => t.Namespace != null && t.Namespace.Contains(".Events."))
            .DefiningMessagesAs(t => t.Namespace != null && t.Namespace.Contains(".Messages."))
            .StructureMapBuilder(new Container(new DependencyRegistry()));

        Configure.Serialization.Json();

        hubConnection = new HubConnection("http://localhost:58120"); 
        hubProxy = hubConnection.CreateHubProxy("AmsHub");
        hubProxy.On<string>("receiveServerPush", x => System.Diagnostics.Debug.WriteLine(x));
        hubConnection.Start().Wait();
    }

    public class DependencyRegistry : Registry
    {
        public DependencyRegistry()
        {
            Scan(x =>
            {
                x.AssembliesFromApplicationBaseDirectory();
                x.ExcludeNamespace("StructureMap");
                x.WithDefaultConventions();
            });
        }
    }
}

What I'm confused about, is how am I supposed to reference the hubConnection and hubProxy in a message handler? I seems like I'm jerry rigging NServicebus.

public class TestHandler : IHandleMessages<AMS.Infrastructure.Events.IEvent>
{
    public void Handle(AMS.Infrastructure.Events.IEvent message)
    {
        EndpointConfig.hubProxy.Invoke("ServerFunction", "yodle");
    }
}

PS: the reason I need the connection and proxy to be global is because spawning up a new hubConnection is expensive according to the signalr people. They highly discourage creating and destroying hubconnections over and over again. They found that making the hubconnection global/static(?) ok though.



Solution 1:[1]

@reed-copsey Old post, but thanks for your reply, it helped me a lot.

In my case I am creating an Azure Function, which will connect to an SignalR Hub which is part of an ASP.NET MVC site. I needed the connection to be secure / authenticated before sending a notification.

So my example included authenticating and getting a cookie.

public class Hub
    {
        private static readonly string HOMEPAGE = ConfigurationManager.AppSettings["Homepage"];
        private static readonly string NOTIFICATION_USER = ConfigurationManager.AppSettings["NotificationUser"];
        private static readonly string NOTIFICATION_PASSWORD = ConfigurationManager.AppSettings["NotificationPassword"];

        private static Lazy<Hub> instance = new Lazy<Hub>(() => new Hub());
        public static Hub Instance { get { return instance.Value; } }

        private Hub()
        {
            ClientHandler = new HttpClientHandler();
            ClientHandler.CookieContainer = new CookieContainer();
            using (Client = new HttpClient(ClientHandler))
            {
                var content = string.Format("Email={0}&Password={1}", NOTIFICATION_USER, NOTIFICATION_PASSWORD);
                var response = this.Client.PostAsync(HOMEPAGE + "/Account/Login", new StringContent(content, Encoding.UTF8, "application/x-www-form-urlencoded")).Result;
            }
            Connection = new HubConnection($"{HOMEPAGE}/");
            Connection.CookieContainer = ClientHandler.CookieContainer;
            Proxy = Connection.CreateHubProxy("notificationsHub");
            //this.Proxy.On<string>("receiveServerPush", x => System.Diagnostics.Debug.WriteLine(x));
            Connection.Start().Wait();
        }

        public HttpClientHandler ClientHandler { get; private set; }
        public HttpClient Client { get; private set; }
        public HubConnection Connection { get; private set; }
        public IHubProxy Proxy { get; private set; }

        public static Task Invoke(string method, params Object[] args)
        {
            return Instance.Proxy.Invoke(method, args);
        }

        public static Task<T> Invoke<T>(string method, params Object[] args)
        {
            return Instance.Proxy.Invoke<T>(method, args);
        }

    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Euan Gordon