gpt4 book ai didi

asp.net-mvc-4 - SignalR、WebAPI 和 MVC 共享相同的依赖解析器内核

转载 作者:行者123 更新时间:2023-12-02 05:54:54 25 4
gpt4 key购买 nike

我有一个带有 SignalRWebAPIASP.NET MVC 应用。该应用程序使用 Ninject 进行依赖项注入(inject),但显然 SignalR 和 WebAPI 正在获取不同的内核,因此它无法共享应为所有应用程序共享的单例对象。

我可以在日志中清楚地看到当 SignalR 收到连接请求时如何创建实例,以及当 WebAPI 收到请求时如何创建实例。

我希望在这三个元素之间共享相同的 Ninject 内核,这样我就可以拥有独特的单例。

这是我到目前为止所做的:

我做的第一件事是创建一个 NinjectModule 声明绑定(bind):

public class MyDependencyModule: NinjectModule
{
public override void Load()
{
var binding = Bind<MustBeSingleton>().ToSelf();
binding.OnActivation((ctx, o) =>
{
Debug.Print("Registering item " + o.GetHashCode());
HostingEnvironment.RegisterObject(o);
});

binding.OnDeactivation(o =>
{
Debug.Print("Unregistering game connection " + o.GetHashCode());
});

binding.InSingletonScope();
}
}

我还为 Ninject 创建了一个包装器,以便将其插入 WebAPI:

public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;

internal NinjectDependencyScope(IResolutionRoot resolver)
{
this.resolver = resolver;
}

public void Dispose()
{
IDisposable disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}

public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");

return resolver.TryGet(serviceType);
}

public IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");

return resolver.GetAll(serviceType);
}
}

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}

public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}

此外,我还为 SignalR 创建了另一个包装器:

public class SignalRNinjectDependencyResolver : DefaultDependencyResolver
{
private readonly IKernel _kernel;

public SignalRNinjectDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}

public override object GetService(Type serviceType)
{
return _kernel.TryGet(serviceType) ?? base.GetService(serviceType);
}

public override IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.GetAll(serviceType).Concat(base.GetServices(serviceType));
}
}

然后我创建了一个 Ninject 内核来完成所有配置:

public class ApplicationDependencies:StandardKernel
{
public ApplicationDependencies()
:base(new MyDependencyModule())
{
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(this);
Microsoft.AspNet.SignalR.GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(this);
}
}

MVC 应用程序使用 NinjectHttpApplication 作为基类,因此我指出必须以这种方式使用的内核:

public class MvcApplication : Ninject.Web.Common.NinjectHttpApplication
{
protected override Ninject.IKernel CreateKernel()
{
return new ApplicationDependencies();
}
}

此外,在 SignalR 配置中,我指定了解析器:

public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR<MyPersistentConnection>("/updates", new ConnectionConfiguration()
{
Resolver = GlobalHost.DependencyResolver
});

}
}

(我也尝试过不指定解析器,但它也不起作用)。

有什么想法吗?

干杯。

最佳答案

我在另一篇文章中找到了答案:Singleton Scope binding not working as intended

必须使用“ToConstant”,而不是绑定(bind)为单例:

var binding = Bind<MustBeSingleton>().ToConstant(new MustBeSingleton());

我使用相同的依赖注入(inject)上下文使用 ASP.NET MVC、WebAPI 和 SignalR 创建了一个简单的演示项目。

https://drive.google.com/file/d/0B52OsuSSsroNX0I5aWFFb1VrRm8/edit?usp=sharing

Web 应用程序包含一个页面,显示一个对象的 AppDomain 和 GetHashCode,该对象在三个框架中应该是唯一的,给出的结果类似于:

Dependency Test

Framework IMySingletonService instance
MVC AppDomainId:2 / HashCode:5109846
WebAPI AppDomainId:2 / HashCode:5109846
SignalR AppDomainId:2 / HashCode:5109846

另一个问题是,Ninject 正在处理我的单例,因为它是 IDisposable。我真的不明白为什么会发生这种情况,但那是另一场 war 。

干杯。

关于asp.net-mvc-4 - SignalR、WebAPI 和 MVC 共享相同的依赖解析器内核,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21002719/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com