J'essaie d'utiliser le conteneur Unity pour faciliter le test unitaire de mes contrôleurs. Mon contrôleur utilise un constructeur qui accepte une interface avec un référentiel. Dans le fichier global.asax, j'instancie UnityContainerFactory et l'enregistre dans le framework MVC, puis enregistre le référentiel et son implémentation. J'ai ajouté l'attribut [Dependency] au paramètre CTOR Repository du contrôleur. Tout semble fonctionner correctement, sauf que, occasionnellement, GetControllerInstance (type controllerType) de l'usine est appelé plus d'une fois et un argument null est passé en tant que controllerType.ASP.NET MVC et Unity 1.2 Container question
Le premier appel à l'usine est toujours correct et le controllerType "ProductsController" est passé en argument. Mais parfois, l'usine est appelée plusieurs fois après que la vue a été affichée avec une valeur nulle pour le contrôleur et je ne sais pas pourquoi. Quand la valeur correcte du type de contrôleur est passée, "Call Stack" a du sens pour moi, mais quand un null est passé, je ne sais pas pourquoi ou qui fait l'appel. Des idées?
Les piles de code et d'appel de l'exemple sont illustrées ci-dessous.
Call Stack est quand fonctionne
TEST.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (System.Type controllerType = {Name = "ProduitsController" FullName = "Test.Controllers.ProductsController"}) Ligne 23 C# TEST.DLL! Test._Default.Page_Load (objet expéditeur = {} ASP.default_aspx, System.EventArgs e = {} System.EventArgs) ligne 18 + 0x1a octets C#
Call Stack lorsque NULL est passé au controllerType
Test.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (Syst em.Type controllerType = null) Ligne 27 C#
D'abord, je créé 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
}
}
}
Ensuite, j'ai ajouté le code suivant le fichier global.asax instancier l'usine de conteneurs
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());
}
L'application a un contrôleur
public class ProductsController : Controller
{
public IProductsRepository productsRepository;
public ProductsController([Dependency]IProductsRepository productsRepository)
{
this.productsRepository = productsRepository;
}
}
Êtes-vous sûr à 100% que cette ligne ne renvoie pas de valeur null: return container.Resolve (controllerType) comme IController; Cela semble peu probable, mais cette distribution pourrait facilement renvoyer une valeur nulle si le type résultant n'était pas un IController ou si l'appel Resolve échouait. –
Salut Anderson, Comme vous pouvez le voir dans la pile des appels, null est transmis. J'ai également arrêté à la ligne en utilisant le débogueur et il est nul avant la distribution. Cet appel est la seule fonction sur la pile à ce moment-là. Ce que je ne comprends pas non plus. Test.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (System.Type controllerType = null) Ligne 27 C# – Rick
C'est ce que je pensais voir dans votre pile, mais je voulais vérifier mes hypothèses pour être sûr. –