我有一些SignalR集线器可能需要访问一些瞬态和单独的依赖项.挂起Hub的创建很容易并且工作正常但是SignalR在创建的Hub上执行自己的Dispose()调用,而不是通知依赖解析器并让它参与处理.
如果依赖项是注册单例,这不是什么大问题,但如果它们被注册为瞬态,那么它们将永远不会被处置(如果需要的话)并且Windsor将保持它们存活直到收集Windsor容器(当无论如何,Web服务器正在关闭).
我看到几种可能的处理方法......
a)这里有人指出了一种方法来将SignalR的HubDispatcher类子类化,以便它可以进行适当的处理.它不是SignalR的标准DependencyResolver的一部分,所以这可能很难/不可能
b)管道中其他地方的SignalR中的其他一些类可以被覆盖或轻松替换,以便我们可以继承HubDispatcher并确保使用子类.据我所知,这将是Owin中间件类HubDispatcherMiddleware.有没有办法迫使Owin不注册这个类,而是注册我自己的版本(这又使用我自己的HubDispatcher)?
c)有一种方法可以拦截SignalR在我的Hub类上进行的Dispose()调用,这样就可以调用Windsor来确保任何依赖关系被正确处理并从容器中释放
d)谨慎地避免使用瞬态生活方式依赖项,而是传入类型化工厂,以便我们可以通过Hub中的类型化工厂解决和释放每个依赖项
目前(d)是我知道该怎么做的唯一一个.(a)或(b)会很棒.(c)主要由本文http://kozmic.net/2010/01/27/transparently-releasing-components-in-windsor/涵盖,但是,拦截器要求通过IDisposable调用Dispose().SignalR的HubDispather类实现了集线器处理
private static void DisposeHubs(IEnumerable<IHub> hubs)
{
foreach (var hub in hubs)
{
hub.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
没有转换到IDisposable那里...... Hub类上的Dispose()是虚拟的,而且博客帖子暗示虚拟Dispose()可能会增加一些复杂性(我不太确定多少,我不太了解无论如何,Castle的拦截器以及是否可以使用IDisposable进行处理.
我很欣赏我已经为一个相当狭隘的观众写了这个问题 - 那些使用过Windsor和SignalR而不仅仅是解决依赖关系的人.我发现的每个例子,包括StackOverflow上的例子,似乎都忽略了依赖关系的发布.
谢谢!
我有一个使用Ninject依赖注入的现有MVC应用程序.我安装了Ninject.MVC3 nuget包,它在我的App_Start中创建了一个名为NinjectWebCommon的类,它完全隔离了内核并注册了我的所有绑定:
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IFoo>().To<Foo>();
}
Run Code Online (Sandbox Code Playgroud)
我们有一个新的要求,我们认为SignalR能够满足,所以我们将SignalR 2 nuget包安装到项目中.我创建了一个Hub并对如何在项目中实现依赖注入进行了一些搜索,并找到了一篇建议创建SignalRDependencyResolver的文章.http://www.asp.net/signalr/overview/signalr-20/extensibility/dependency-injection
本文让您在Startup.cs文件中创建一个内核,用于在OWIN中注册SignalR:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var kernel = new StandardKernel();
var resolver = new NinjectSignalRDependencyResolver(kernel);
kernel.Bind<IStockTicker>()
.To<Microsoft.AspNet.SignalR.StockTicker.StockTicker>() // Bind to StockTicker.
.InSingletonScope(); // Make it a singleton object.
kernel.Bind<IHubConnectionContext>().ToMethod(context =>
resolver.Resolve<IConnectionManager>().GetHubContext<StockTickerHub>().Clients …Run Code Online (Sandbox Code Playgroud) 在自托管应用程序中使用SignalR 2.0,根据这些说明,您可以这样:
class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR(new HubConfiguration { Resolver = ... });
}
}
class Program
{
static void Main(string[] args)
{
using (WebApp.Start("http://localhost:8080")) // constructs Startup instance internally
{
Console.WriteLine("Server running on {0}", url);
Console.ReadLine();
}
}
}
Run Code Online (Sandbox Code Playgroud)
您会注意到Startup类实例是使用一些幕后魔术创建的.我无法弄清楚如何填写依赖关系.有没有办法覆盖Startup类的构造,以便我可以注入依赖项?