2009-09-16 5 views
11

J'utilise Castle Windsor pour gérer les instances de contrôleur (entre autres). Mon usine de contrôleur ressemble à ceci:Pourquoi GetControllerInstance() de mon usine de contrôleur Castle Windsor est-il appelé avec une valeur nulle?

public class WindsorControllerFactory : DefaultControllerFactory 
    { 
     private WindsorContainer _container; 

     public WindsorControllerFactory() 
     { 
      _container = new WindsorContainer(new XmlInterpreter()); 

      var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes() 
            where typeof(Controller).IsAssignableFrom(t) 
            select t; 

      foreach (Type t in controllerTypes) 
      { 
       _container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient); 
      } 
     } 

     protected override IController GetControllerInstance(Type controllerType) 
     { 
      return (IController)_container.Resolve(controllerType); // ArgumentNullException is thrown here 
     } 

Lorsque je démarre mon application ASP.Net MVC et essayer d'aller à «/» (ou un autre chemin), je reçois un ArgumentNullException. J'ai mis un point d'arrêt à l'entrée de GetControllerInstance et j'ai trouvé qu'il s'appelait une fois avec mon HomeController, puis une seconde fois avec null (qui est quand l'exception est levée). Pourquoi est-il appelé à nouveau?

ce que je devrais changer la méthode à quelque chose comme:

protected override IController GetControllerInstance(Type controllerType) 
{ 
    if (controllerType == null) 
     return null; 

    return (IController)_container.Resolve(controllerType); 
} 
+0

Pourquoi vous entaillez l'enregistrement avec la réflexion au lieu d'utiliser l'API d'inscription appropriée? –

+0

@Krzysztof - Je suivais l'exemple de Steve Sanderson. Si vous souhaitez publier un meilleur moyen d'enregistrer toutes les classes qui héritent du contrôleur, veuillez le faire. – scottm

Répondre

24

Il se trouve que la deuxième demande était le framework MVC en essayant de trouver un script que j'inclus dans le Site.master. Le chemin n'existait pas, donc je suppose qu'il a essayé de résoudre un contrôleur (qui correspondait à /Scripts/sitescripts.js). J'ai changé la méthode à ceci:

protected override IController GetControllerInstance(Type controllerType) 
{ 
    if (controllerType != null) 
    { 
     return (IController)_container.Resolve(controllerType); 
    } 
    else 
    { 
     return base.GetControllerInstance(controllerType); 
    } 
} 

Et une exception avec un message compréhensible a été levée.

+1

Merci, j'ai passé des heures à chercher cette solution. – Geo

+0

Merci, m'a aidé aussi. –

+1

Et moi trois. Juste pour noter, pour MVC 2.0, c'est return base.GetControllerInstance (requestContext, controllerType); – Gabe

4

eu ce problème en suivant le livre Pro ASP.NET MVC Framework, a ajouté

routes.IgnoreRoute ("favicon.ico");

aux routes du fichier global.asax.cs et cela fonctionne. Voir plus ici: serving favicon.

+0

Avait le même problème que le gars posant la question et tandis que la meilleure gestion des erreurs est une bonne idée, le problème était que la page était en cours de chargement chercher la favicon. Ajouter la ligne ci-dessus a résolu mon problème tout de suite. – colethecoder

+0

@colethecoder Heureux qu'il a aidé –

3

concernant l'enregistrement de tous les contrôleurs que vous auriez habituellement le faire comme ceci:

container.Register(
    AllTypes.FromThisAssembly() 
     .BasedOn<IController>() 
     .Configure(c => c.Lifestyle.Transient) 
); 

Voir the documentation pour plus d'explication de l'API.

Questions connexes