gpt4 book ai didi

asp.net-mvc - ASP.NET MVC 和 Unity 1.2 容器问题

转载 作者:行者123 更新时间:2023-12-02 06:21:20 24 4
gpt4 key购买 nike

我正在尝试使用 Unity 容器来更轻松地对我的 Controller 进行单元测试。我的 Controller 使用接受存储库接口(interface)的构造函数。在 global.asax 文件中,我实例化一个 UnityContainerFactory 并将其注册到 MVC 框架,然后注册存储库及其实现。我将 [Dependency] 属性添加到 Controller 的 CTOR Repository 参数中。这一切似乎都工作正常,除了偶尔会多次调用工厂的 GetControllerInstance(Type controlType) 并传递一个 null 参数作为controllerType。

对工厂的第一次调用完全正确,并且 Controller 类型“ProductsController”作为参数传入。但有时,在 View 显示 Controller 的空值后,工厂会被多次调用,我不确定为什么。当传递 Controller 类型的正确值时,“调用堆栈”对我来说有意义,但是当传递 null 时,我不确定为什么或谁在进行调用。有什么想法吗?

该示例的代码和调用堆栈如下所示。

工作时调用堆栈

Test.DLL!Test.UnityHelpers.UnityControllerFactory.GetControllerInstance(System.Type controllerType = {Name = "ProductsController"FullName = "Test.Controllers.ProductsController"}) 第 23 行 C#Test.DLL!Test._Default.Page_Load(object sender = {ASP.default_aspx}, System.EventArgs e = {System.EventArgs}) 第 18 行 + 0x1a 字节 C#

在 Controller 类型传递 NULL 时调用堆栈

Test.DLL!Test.UnityHelpers.UnityControllerFactory.GetControllerInstance(System.TypecontrollerType = null) 第 27 行 C#

首先我创建了一个 UnityControllerFactory

public class UnityControllerFactory : DefaultControllerFactory
{
UnityContainer container;

public UnityControllerFactory(UnityContainer container)
{
this.container = container;
}

protected override IController GetControllerInstance(Type controllerType)
{
if (controllerType != null)
{
return container.Resolve(controllerType) as IController;
}
else
{
return null; // I never expect to get here, but I do sometimes, the callstack does not show the caller
}
}
}

接下来,我在 global.asax 文件中添加了以下代码来实例化容器工厂

    protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);

// Create Unity Container if needed
if (_container == null)
{
_container = new UnityContainer();
}

// Instantiate a new factory
IControllerFactory unityControllerFactory = new UnityControllerFactory(_container);

// Register it with the MVC framework
ControllerBuilder.Current.SetControllerFactory(unityControllerFactory);

// Register the SqlProductRepository
_container.RegisterType<IProductsRepository, SqlProductRepository>
(new ContainerControlledLifetimeManager());
}

该应用程序有一个 Controller

public class ProductsController : Controller
{
public IProductsRepository productsRepository;

public ProductsController([Dependency]IProductsRepository productsRepository)
{
this.productsRepository = productsRepository;
}
}

最佳答案

这可能是由于某些文件类型未映射到路由中的 Controller 。 (例如图像)。根据我的经验,当您使用 Cassini 进行本地调试时,这种情况会更常见,因为 Cassini 允许所有请求通过 ASP.NET 路由,而在 IIS 中,许多请求由 IIS 为您处理。这也是您在堆栈中看不到此请求的代码的原因。如果您在 Visual Studio 中关闭“仅我的代码”选项,有时可以获得有关这些事情的更好提示。

虽然这不是发生这种情况的唯一原因,但很常见。

适当的做法是允许基本方法处理这些情况下的请求。它通常只是一个简单的文件请求,不会对您产生任何影响。

最简单的事情就是像这样设置门:

    if (controllerType != null)
{
return container.Resolve(controllerType) as IController;
}
else
{
return base.GetControllerInstance(requestContext, controllerType);
}

应该可以了。

要查看请求的用途,您可以检查 HttpContext.Current.Request 以查看哪些文件不在您的路由中。很多时候,这不是您想要控制的事情,但知道请求的来源会让您感觉更好。

关于asp.net-mvc - ASP.NET MVC 和 Unity 1.2 容器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1308928/

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