2009-09-16 12 views
11

Używam Castle Windsor do zarządzania instancjami kontrolerów (między innymi). Mój zakład kontroler wygląda następująco:Dlaczego moja fabryka kontrolera GetControllerInstance() mojego zamku Windsor jest wywoływana z wartością pustą?

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 
     } 

Kiedy uruchomić mojej aplikacji ASP.Net MVC i starają się iść na „/” (lub inna ścieżka), otrzymuję ArgumentNullException. Wprowadziłem przerwę w wejściu do GetControllerInstance i stwierdziłem, że jest ono wywoływane raz z moim HomeControllerem, a następnie po raz drugi z wartością null (która jest wtedy, gdy zgłoszony zostanie wyjątek). Dlaczego jest on ponownie wywoływany?

Czy mogę zmienić metodę do czegoś takiego:

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

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

Czemu hacking rejestrację z refleksji zamiast używać odpowiedniego API rejestracyjny? –

+0

@ Krzysztof - Podążałem za przykładem Steve Sandersona. Jeśli chcesz opublikować lepszy sposób rejestrowania wszystkich klas dziedziczących po kontrolerze, zrób to. – scottm

Odpowiedz

24

Okazuje się, że druga prośba była framework MVC próbuje znaleźć skrypt I zawarte w Site.Master. Ścieżka nie istnieje, więc domyślam się, że próbował rozwiązać kontroler (pasujący do /Scripts/sitescripts.js). Zmieniłem metodę na:

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

Wyrzucono wyjątek ze zrozumiałą wiadomością.

+1

Dzięki, spędziłem godziny szukając tego rozwiązania. – Geo

+0

Dzięki, pomógł mi również. –

+1

A ja trzy. Uwaga: w przypadku MVC 2.0 to ta baza danych: .GetControllerInstance (requestContext, controllerType); – Gabe

4

miał ten problem, gdy po książki Pro ASP.NET MVC Framework dodał

routes.IgnoreRoute ("favicon.ico");

do tras w pliku global.asax.cs i to działa. Zobacz więcej tutaj: serving favicon.

+0

Miał ten sam problem, co facet zadający pytanie i chociaż lepsze rozwiązywanie błędów jest dobrym pomysłem, problem polegał na tym, że strona ładowała się, a następnie przechodziła szukać favicon. Dodanie powyższej linii rozwiązało mój problem od razu. – colethecoder

+0

@colethecoder Cieszę się, że pomogło –

3

dotyczące rejestracji wszystkich kontrolerów, którą zazwyczaj robią to tak:

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

Zobacz the documentation więcej wyjaśnieniem API.