2013-09-02 13 views
13

Próbuję usunąć niektóre problemy ze starszej wersji kodu. Sądzę, że przyczyną jest wyjątek, ponieważ coś nie może zostać rozwiązane z kontenera Autofac. Jednak myślę, że wyjątek jest gdzieś pochowany i nie widzę przyczyny. Jestem pewien, że coś jest żądane od kontrolera, którego nie można znaleźć lub coś, co można znaleźć, ma zależność, której nie można zaspokoić. Nie ma żadnych klauzul strażniczych itp., Więc myślę, że otrzymuję zerowy numer referencyjny. Aby spróbować to debugować, chcę zobaczyć wszystkie żądania, które nie znajdują się w kontenerze.Jak mogę zarejestrować wszystkie żądania rozstrzygnięcia w kontenerze Autofac?

Czy mimo to rejestruje się wszystkie żądania, których Autofac nie mógł rozwiązać? Lub alternatywnie wystarczy zalogować wszystkie żądania do kontenera?

Odpowiedz

30

Możesz dodać rejestrowanie żądań do pojemnika rejestracji specjalny moduł, który złapie zdarzenie Preparing dla wszystkich rejestracji:

public class LogRequestsModule : Module 
{ 
    protected override void AttachToComponentRegistration(
    IComponentRegistry componentRegistry, 
    IComponentRegistration registration) 
    { 
    // Use the event args to log detailed info 
    registration.Preparing += (sender, args) => 
     Console.WriteLine(
     "Resolving concrete type {0}", 
     args.Component.Activator.LimitType); 
    } 
} 

Jest to najprostszy sposób, aby przejść i prawdopodobnie będzie Ci to, co chcesz . Zaraz po zdarzeniu Preparing rejestruje informacje, zobaczysz wyskakujący wyjątek, a dowiesz się, który komponent rzucił.

Jeśli chcesz uzyskać bardziej wyszukane, można skonfigurować niektóre obsługi zdarzeń na pojemniku ChildLifetimeScopeBeginning, ResolveOperationBeginning, ResolveOperationEnding i CurrentScopeEnding wydarzeń.

  • Podczas ChildLifetimeScopeBeginning trzeba by założyć coś do automatycznego dołączania do każdego życia dziecka ResolveOperationBeginning imprez.
  • Podczas ResolveOperationBeginning rejestrowałeś to, co zostanie rozwiązane.
  • Podczas rejestracji ResolveOperationEnding rejestrowane są wszystkie wyjątki.
  • Podczas CurrentScopeEnding trzeba zrezygnować z jakichkolwiek wydarzeń w tym zakresie, aby moduł czyszczący mógł wyczyścić cały okres z wszystkimi jego instancjami.

The Whitebox profiler project has a module, który implementuje niektóre z tych bardziej zaawansowanych logowania, ale to nie jest skonfigurowany do najnowszej Autofac więc trzeba by użyć go jako punkt wyjścia, a nie próbki wytnij/wklej.

Ponownie, najprostszym rozwiązaniem jest ten moduł, który napisałem powyżej.

+5

Znam marszczy brwi na podziękowania. Jednak naprawdę doceniam wysiłek, jaki włożyliście w udzielanie odpowiedzi na pytania Autofac. Odpowiedzi są zawsze bardzo szczegółowe. – GraemeMiller

+0

Właśnie za mniej wstrzykniętą zależność, tak jak ja, tak rejestrujesz ten moduł: builder.RegisterModule (); –

+0

Travis dziękuje za odpowiedź, czy mógłbyś pokazać fragment kodu, jak rejestrować nazwę zakresu rozwiązanego typu? –

19

Tylko po to, aby uzyskać doskonałą odpowiedź od Travis, na wypadek gdyby ktoś pomógł w przyszłości.

Jeśli twoja struktura klasowa jest bardzo głęboka, może być łatwiej dostrzec problematyczną ścieżkę, jeśli wyświetlasz obiekty w hierarchii kompozycji. Można to osiągnąć z somehting tak: wyjście

using System; 
using System.Text; 
using Autofac; 
using Autofac.Core; 

namespace Tests 
{ 
    public class LogRequestModule : Module 
    { 
     public int depth = 0; 

     protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, 
                   IComponentRegistration registration) 
     { 
      registration.Preparing += RegistrationOnPreparing; 
      registration.Activating += RegistrationOnActivating; 
      base.AttachToComponentRegistration(componentRegistry, registration); 
     } 

     private string GetPrefix() 
     { 
      return new string('-', depth * 2); 
     } 

     private void RegistrationOnPreparing(object sender, PreparingEventArgs preparingEventArgs) 
     { 
      Console.WriteLine("{0}Resolving {1}", GetPrefix(), preparingEventArgs.Component.Activator.LimitType); 
      depth++; 
     } 

     private void RegistrationOnActivating(object sender, ActivatingEventArgs<object> activatingEventArgs) 
     { 
      depth--;  
      Console.WriteLine("{0}Activating {1}", GetPrefix(), activatingEventArgs.Component.Activator.LimitType); 
     } 
    } 
} 

Próbka:

--Resolving SomeProject.Web.Integration.RestApiAdapter.RestApiAdapter 
----Resolving SomeProject.Web.Integration.RestApiAdapter.Client.ClientFactory 
------Resolving SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration 
------Activating SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration 
------Resolving SomeProject.Web.Integration.RestApiAdapter.Client.Authentication.ApiClientAuthenticationService 
--------Resolving SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration 
--------Activating SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration 
------Activating SomeProject.Web.Integration.RestApiAdapter.Client.Authentication.ApiClientAuthenticationService 
+1

GetPrefix() może zwrócić nowy ciąg ('-', _depth * 2); – angularsen

+0

Dobra sugestia, zaimplementowana, byłem zbyt gadatliwy –

+1

Nitpicking, ale z pewnością "depth" powinien być właściwością instancji, a nie statyczną. Szanse na wykorzystanie dwóch jednocześnie są wyraźnie odległe, ale mimo to ... – piers7

Powiązane problemy