iti*_*tim 14 c# autofac signalr owin
摘自:http://docs.autofac.org/en/latest/integration/signalr.html:
"OWIN集成中的常见错误是使用GlobalHost.在OWIN中,您可以从头开始创建配置.在使用OWIN集成时,不应该在任何地方引用GlobalHost."
这听起来很合理.但是,如何IHubContext通过ApiController解析,就像通常的(非OWIN):
GlobalHost.ConnectionManager.GetHubContext<MyHub>()?
我无法在任何地方找到这个参考,我现在唯一的方法是HubConfiguration在同一个容器中注册实例并执行此操作:
public MyApiController : ApiController {
public HubConfiguration HubConfig { get; set; } // Dependency injected by
// PropertiesAutowired()
public IHubContext MyHubContext {
get {
return HubConfig
.Resolver
.Resolve<IConnectionManager>()
.GetHubContext<MyHub>();
}
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
但是,这对我来说似乎相当冗长.这样做的正确方法是什么?更具体一点,是否有一种干净的注册方式IConnectionManager?
编辑:
我最终做的是:
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);
Run Code Online (Sandbox Code Playgroud)
但我觉得必须有一种更简单的方法来IConnectionManager注入控制器.
Jam*_*all 15
这个答案有点迟了但是这里有.
public interface IMyHub
{
// Any methods here for strongly-typed hubs
}
[HubName("myHub")]
public class MyHub : Hub<IMyHub>
Run Code Online (Sandbox Code Playgroud)
来自您的Autofac注册
// 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);
Run Code Online (Sandbox Code Playgroud)
使用AutoFacs AutowiredProperties()扩展方法然后它可以解析正确的上下文(如果你愿意,也可以在构造函数中).
public IHubContext<IMyHub> InstanceHubContext { get; [UsedImplicitly] set; }
Run Code Online (Sandbox Code Playgroud)
你可以做的是将一些重复的代码(我假设IHubContext也用于其他一些类,并以相同的方式提取)进入容器注册.
首先是注册IHubContext实例,我假设你在项目中有多个集线器.在这种情况下,服务必须注册为命名服务.
builder
.Register<IHubContext>(c => c.Resolve<IConnectionManager>().GetHubContext<MyHub>())
.Named<IHubContext>("MyHub");
Run Code Online (Sandbox Code Playgroud)
想要使用的类IHubContext现在可以作为构造函数参数或属性接收它.但是我们必须告诉容器它应该注入哪个实例.这可以通过多种方式在容器配置中完成
构造函数可以ResolvedParameter用来正确选择IHubContext实现
// example class
public class SampleClass {
public SampleClass(IHubContext context) { }
}
// and registration for this class
builder.RegisterType<SampleClass>()
.WithParameter(new ResolvedParameter((pi, ctx) =>
{
// only apply this to parameters of IHubContext type
return pi.ParameterType == typeof(IHubContext);
}, (pi, ctx) =>
{
// resolve context
return ctx.ResolveNamed<IHubContext>("MyHub");
}));
Run Code Online (Sandbox Code Playgroud)
物业注入,也有点棘手.需要在OnActivated回调中解析正确的实例,例如:
// example class
public class SampleClass2
{
public IHubContext Context { get; set; }
}
// registration for this case
builder.RegisterType<SampleClass2>()
.PropertiesAutowired()
.OnActivated(e => e.Instance.Context = e.Context.ResolveNamed<IHubContext>("MyHub"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4694 次 |
| 最近记录: |