gpt4 book ai didi

asp.net-mvc - AccountController 和 Ninject 2 以及 ASP.NET MVC 2 Preview 2 出现错误

转载 作者:行者123 更新时间:2023-12-02 03:32:45 24 4
gpt4 key购买 nike

我正在使用 Ninject 2 和 Ninject.Web.MVC 并使用 NinjectHttpApplication

在登录过程中收到以下错误:“ Controller ‘MySite.Controllers.AccountController’的单个实例不能用于处理多个请求。如果正在使用自定义 Controller 工厂,请确保它为每个请求创建一个新的 Controller 实例。”

我的 global.asax 有这个:

 protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);


RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}
protected override IKernel CreateKernel()
{
return new StandardKernel(new MySite.IoCModules.FakeRepositoriesModule(), new MySite.IoCModules.AccountControllerModule());
}

AccountControllerModule 看起来像这样:

 public class AccountControllerModule:Module
{
public override void Load()
{
Bind<IFormsAuthentication>().To<FormsAuthenticationService>();
Bind<IMembershipService>().To<AccountMembershipService>();
Bind<MembershipProvider>().ToConstant(Membership.Provider);
}
}

我的猜测是它与 RegisterAllControllersIn 期间设置的生命周期有关...但我只是不确定...有什么想法可以从这里开始吗?

更新:刚刚看到 HomeController 也发生了这种情况...它必须尝试从中创建一个单例还是正确的?

最佳答案

最新版本的 Ninject.Web.Mvc 使用 transient 作用域在 RegisterAllControllersIn 中注册 Controller :

public void RegisterAllControllersIn(Assembly assembly, 
Func<Type, string> namingConvention)
{
foreach (Type type in assembly.GetExportedTypes().Where(IsController))
_kernel.Bind<IController>()
.To(type)
.InTransientScope()
.Named(namingConvention(type));
}

我还研究了 NinjectControllerFactory 类。它的 CreateController 函数非常基本。它在内核上为 Controller 执行 TryGet 并返回它返回的内容 - 如果找不到 Controller ,它将委托(delegate)给基类:

public override IController CreateController(RequestContext requestContext, 
string controllerName)
{
var controller = Kernel.TryGet<IController>(controllerName.ToLowerInvariant());

if (controller == null)
return base.CreateController(requestContext, controllerName);

var standardController = controller as Controller;

if (standardController != null)
standardController.ActionInvoker = new NinjectActionInvoker(Kernel);

return controller;
}

因此,根据绑定(bind)设置和工厂,它似乎没有在 Singleton 范围内创建对象。您可以做的一件事是在创建内核后编写一些调试代码并亲自检查绑定(bind)以确认范围是什么。我做了一个小实验,并将代码添加到我的 HttpApplication 类中,如下所示。完全公开,这是使用 ASP.Net MVC 1.0,因此您的情况可能会有所不同。如果有机会,我会获取最新的 MVC 2 预览版并尝试相同的实验。

protected void DumpBindings() {
var bindings = Kernel.GetBindings(typeof(IController));

var dummyRequest = new RequestContext(
new HttpContextWrapper(HttpContext.Current),
new RouteData());

foreach (var binding in bindings) {
var scope = "Custom";
if (binding.ScopeCallback == StandardScopeCallbacks.Request)
scope = "Request";
else if (binding.ScopeCallback == StandardScopeCallbacks.Singleton)
scope = "Singleton";
else if (binding.ScopeCallback == StandardScopeCallbacks.Thread)
scope = "Thread";
else if (binding.ScopeCallback == StandardScopeCallbacks.Transient)
scope = "Transient";

HttpContext.Current.Trace.Write(
string.Format(
"Controller: {0} Named: {1} Scope: {2}",
binding.Service.Name,
binding.Metadata.Name,
scope));
var controllerFactory = ControllerBuilder.Current.GetControllerFactory();

var controller1 = controllerFactory.CreateController(
dummyRequest, binding.Metadata.Name);
var controller2 = controllerFactory.CreateController(
dummyRequest, binding.Metadata.Name);

HttpContext.Current.Trace.Write(
string.Format(
"{0} controller1 == {0} controller2 ? {1}",
binding.Metadata.Name,
object.Equals(controller1, controller2)));
}
}

我在 OnApplicationStarted 中调用 RegisterAllControllersIn 后立即调用了此函数。它在跟踪输出中创建了以下消息:

Controller: IController Named: home
Scope: Transient home controller1
== home controller2 ? False Controller: IController Named: account
Scope: Transient account controller1
== account controller2 ? False

因此,这一切都是为了确认正在使用 transient 作用域,并且 Controller 工厂在请求时返回同一 Controller 的不同实例。所以,我唯一能想到的是:

  1. 也许您没有使用最新版本的 Ninject 2 和 Ninject.Web.Mvc
  2. 问题出在 MVC 级别 - 即它重用了工厂创建的 Controller

关于asp.net-mvc - AccountController 和 Ninject 2 以及 ASP.NET MVC 2 Preview 2 出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1719249/

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