Estoy tratando de usar el contenedor Unity para que resulte más fácil probar mis controladores unitarios. Mi controlador usa un constructor que acepta una interfaz para un Repositorio. En el archivo global.asax, instalo un UnityContainerFactory y lo registro con el framework MVC y luego registro el repositorio y su implementación. Agregué el atributo [Dependency] al parámetro del Depósito CTOR del controlador. Todo parece funcionar bien, excepto que ocasionalmente se llama al GetControllerInstance (Type controllerType) de la fábrica más de una vez y se pasa un argumento nulo como el controllerType.ASP.NET MVC y Unity 1.2 Pregunta de contenedor
La primera llamada a la fábrica es siempre correcta y el ControllerType "ProductsController" se transfiere como argumento. Pero a veces, la fábrica se llama un par de veces más después de que la vista se haya mostrado con un valor nulo para el controlador y no estoy seguro de por qué. Cuando se pasa el valor correcto del tipo de controlador, "Call Stack" tiene sentido para mí, pero cuando se pasa un nulo, no estoy seguro de por qué o quién está haciendo la llamada. ¿Algunas ideas?
El código y las pilas de llamadas para el ejemplo se muestran a continuación.
pila de llamadas cuando se trabaja
test.dll! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (System.Type controllerType = {Nombre = "ProductsController" FullName = "Test.Controllers.ProductsController"}) Línea 23 C# test.dll! Test._Default.Page_Load (object sender = {} ASP.default_aspx, System.EventArgs e = {} System.EventArgs) Línea 18 + 0x1a bytes C#
pila de llamadas cuando se pasa NULL en el controllerType
Test.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (Syst em.Type controllerType = null) Línea 27 C#
Primero creé un 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
}
}
}
A continuación, he añadido el siguiente código en el archivo Global.asax para crear instancias de la fábrica de envases
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());
}
La aplicación tiene un controlador
public class ProductsController : Controller
{
public IProductsRepository productsRepository;
public ProductsController([Dependency]IProductsRepository productsRepository)
{
this.productsRepository = productsRepository;
}
}
¿Está 100% seguro de que esta línea no devuelve nulo: return container.Resolve (controllerType) como IController; Parece poco probable, pero ese molde podría devolver nulo fácilmente si el tipo resultante no era un IController o la llamada Resolver falló. –
Hola Anderson, Como puedes ver en la pila de llamadas, se está pasando nulo. También detuve en la línea usando el depurador y es nulo antes del lanzamiento. Esta llamada es la única función en la pila en ese momento. Lo cual tampoco entiendo. Test.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (System.Type controllerType = null) Línea 27 C# – Rick
Eso es lo que pensé que estaba viendo en tu pila, pero quería verificar mis suposiciones para asegurarme. –