Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
293 views
in Technique[技术] by (71.8m points)

c# - OWIN + SignalR + Autofac

Taken from: http://docs.autofac.org/en/latest/integration/signalr.html:

"A common error in OWIN integration is use of the GlobalHost. In OWIN you create the configuration from scratch. You should not reference GlobalHost anywhere when using the OWIN integration."

That sounds reasonable. However, how should one resolve IHubContext from an ApiController, like the usual (non-OWIN):

GlobalHost.ConnectionManager.GetHubContext<MyHub>()?

I can't find a reference on this one anywhere, and the only method I have by now is to register the HubConfiguration instance within the same container and do this:

public MyApiController : ApiController {
  public HubConfiguration HubConfig { get; set; } // Dependency injected by
                                                  // PropertiesAutowired()

  public IHubContext MyHubContext { 
    get { 
      return HubConfig
        .Resolver
        .Resolve<IConnectionManager>()
        .GetHubContext<MyHub>(); 
     } 
  }

  // ...

}

However, this seems quite verbose to me. What is the proper way to do it? To be more specific, is there a clean way to register IConnectionManager?

EDIT:

What I ended up doing is something like:

var container = builder.Build();
hubConfig.Resolver = new AutofacDependencyResolver(container); 

app.MapSignalR("/signalr", hubConfig);

var builder2 = new ContainerBuilder();
builder2
  .Register(ctx => hubConfig.Resolver.Resolve<IConnectionManager>())
  .As<IConnectionManager>();

builder2.Update(container);

but I have a feeling there must be an easier way to get that IConnectionManager injected in the controller.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This answer is a little belated but here goes.

  • I recommend strongly typed hubs.
  • You need to add specific registrations for the strongly typed hubs.
  • I don't use the GlobalHost
    • Instead I use the Configuration created for OWIN registration.

Hub Declaration

public interface IMyHub
{
    // Any methods here for strongly-typed hubs
}

[HubName("myHub")]
public class MyHub : Hub<IMyHub>

Hub Registration

From your Autofac registration

// SignalR Configuration
var signalRConfig = new HubConfiguration();

var builder = // Create your normal AutoFac container here

builder.RegisterType<MyHub>().ExternallyOwned(); // SignalR hub registration

// Register the Hub for DI (THIS IS THE MAGIC LINE)
builder.Register(i => signalRConfig.Resolver.Resolve<IConnectionManager>().GetHubContext<MyHub, IMyHub>()).ExternallyOwned();

// Build the container
var container = builder.Build();

// SignalR Dependency Resolver
signalRConfig.Resolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);

app.UseAutofacMiddleware(container);
app.MapSignalR("/signalr", signalRConfig);

Resolving the hub in background code

Using AutoFacs AutowiredProperties() extension method then it can resolve the correct context (can also be in the constructor if you like).

public IHubContext<IMyHub> InstanceHubContext { get; [UsedImplicitly] set; }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...