我正在尝试使用 Unity 容器来更轻松地对我的控制器进行单元测试。我的控制器使用一个构造函数,该构造函数接受一个存储库的接口。在 global.asax 文件中,我实例化了一个 UnityContainerFactory 并将其注册到 MVC 框架,然后注册存储库及其实现。我将 [Dependency] 属性添加到控制器的 CTOR 存储库参数中。这一切似乎都可以正常工作,只是偶尔会多次调用工厂的 GetControllerInstance(Type controllerType) 并将 null 参数作为 controllerType 传递。
对工厂的第一次调用是正确的,并且控制器类型“ProductsController”作为参数传入。但有时,在控制器的视图显示为空值后,工厂被调用了几次,我不知道为什么。当传递控制器类型的正确值时,“调用堆栈”对我来说是有意义的,但是当传递空值时,我不确定为什么或谁在进行调用。有任何想法吗?
该示例的代码和调用堆栈如下所示。
工作时调用堆栈
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#
在 controllerType 传递 NULL 时调用 Stack
Test.DLL!Test.UnityHelpers.UnityControllerFactory.GetControllerInstance(System.Type controllerType = 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());
}
该应用程序有一个控制器
public class ProductsController : Controller
{
public IProductsRepository productsRepository;
public ProductsController([Dependency]IProductsRepository productsRepository)
{
this.productsRepository = productsRepository;
}
}