Skip to content
davidfowl edited this page May 12, 2012 · 27 revisions

Extensiblity

SignalR is built with dependency injection in mind. You can replace most of SignalR pieces with your own implementations and even replace the IDependencyResolver with one of your own. If you're familiar with DI in ASP.NET MVC, then it should feel similar.

Replacing individual components

You can replace individual parts of SignalR without replacing the DependencyResolver by calling

GlobalHost.DependencyResolver.Register(type, Func<object>):
GlobalHost.DependencyResolver.Register(typeof(IConnectionIdFactory), () => new CustomIdFactory());

Replaceable components

The following lists the pluggable interfaces in SignalR.

  • IMessageBus - Message bus.
  • IConnectionIdGenerator - Generates connection ids.
  • IAssemblyLocator - Locates assemblies to find hubs in.
  • IJavaScriptProxyGenerator - Generates the client proxy for hubs.
  • IJavaScriptMinifier - Allows the dynamic javascript proxy to be minified.
  • IJsonSerializer - Used to serialize and deserialze outgoing/incoming data.

Replacing the IJsonSerializer

If you want to add custom serialization logic, you can replace the default IJsonSerializer. This may be useful for doing things like changing the default date format or using custom serialization settings.

NOTE: SignalR's clients are case sensitive so do not change the case of members when serializing.

The following sample shows an implementation that changes the default date format to the MicrosoftDateFormat in JSON.NET.

public class CustomJsonNetSerializer : IJsonSerializer
{
    private readonly JsonSerializerSettings _settings;

    public CustomJsonNetSerializer(JsonSerializerSettings settings)
    {
        _settings = settings;
    }
   
    public string Stringify(object obj)
    {
        return JsonConvert.SerializeObject(obj, _settings);
    }
  
    public object Parse(string json)
    {
        return JsonConvert.DeserializeObject(json);
    }
 
    public object Parse(string json, Type targetType)
    {
        return JsonConvert.DeserializeObject(json, targetType);
    }

    public T Parse<T>(string json)
    {
        return JsonConvert.DeserializeObject<T>(json);
    }
}

You can register this custom serializer in Global.asax.

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        var serializer = new CustomJsonNetSerializer(new CustomJsonNetSerializer(new JsonSerializerSettings
        {
            DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
            NullValueHandling = NullValueHandling.Ignore
        });

        GlobalHost.DependencyResolver.Register(typeof(IJsonSerializer), () => serializer); 
    }
}

Replacing the DependencyResolver

You can change the DependencyResolver to use your DI container of choice by setting GlobalHost.DependencyResolver.

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        GlobalHost.DependencyResolver = new CustomResolver();
 
        RouteTable.Routes.MapHubs();
    }
}

Optionally, if you don't want to use the global resolver you can set the resolver for specific connections when routes:

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        RouteTable.Routes.MapHubs(new CustomResolver());
    }
}

There are already some implementations in the community:

Clone this wiki locally