2009-08-24 12 views
5

Przeszedłem przez kilka z tych pytań, leżących na różnych stronach i odpowiedzi wydają się być wirowane przez l4n officianados w kierunku wartości lekkiego opakowania, które log4net "jest" (nie dostałeś to?) i podobne punkty zdumiewającego faktu.ponownie o log4net i Unity IOC config

Jednak wydaje się, że to, o co proszą użytkownicy (a to jest moje pytanie), to jak dopasować log4net objet do sekwencji rejestrów/rejestrów w płynnym interfejsie konfiguracyjnym.

Celem tutaj nie byłoby ponowne owinięcie l4n, ale po prostu uchwycenie przyzwoitego odniesienia, które nie wymaga "przejmowania płynnego przepływu".

słabe ejemplow, chcę uzyskać odniesienie do skonfigurowanej instancji ILog z metody LogManger.GetLogger i wprowadzić ją do płynnego przepływu wystarczająco wcześnie, aby wprowadzić go do właściwości moich dalszych obiektów.

Więc w odpowiedzi na jeden niecierpliwy sugestią, próbowałem stworzył normalny wystąpienie Ilog w kanonicznym sposób:

log4net.Config.XmlConfigurator.Configure(); 
static readonly log4Net.Ilog Log = LogManager.GetLogger(thatlongassemblyreflectionstuff); 

Więc to wydawać banalne (w prawdziwym znaczeniu tego wysiłku), aby teraz dodać, że odwołanie do pojemnika Unity i zabierz się za moje cudowne życie.

Jednak podpis dla metody RegisterInstance wymaga "Typu", a nie interfejsu.

Dla tych, którzy nie przeszukali modelu obiektu log4net, afficiananderos są poprawne: l4n jest "opakowaniem" i nie można uzyskać rzeczywistego "typu" dla logu.

Teraz muszę przetestować. Wiesz, co to oznacza, może to zająć chwilę, ale najprawdopodobniej zajmie godzinę lub cztery (podobne cechy, jak pisownia "godziny" i "czwórki", nigdy nie są przypadkowe w prawdziwym życiu).

Jednak dodaje, minus pomijana część o kanonicznej konfiguracji, czy praca:

container 
    .RegisterInstance("Logger", Log, new ContainerControlledLifetimeManager()) 
.RegisterType<IControllerContext, ControllerContext> 
(
    "CtlrCtx", 
    new ContainerControlledLifetimeManager(), 
    new InjectionConstructor(new ResolvedParameter<IMessageBuilder>("MsgBldr")), 
    new InjectionProperty("Log",new ResolvedParameter<ILog>("Logger")) 
); 

tak więc hashcodes o oryginalnym obiektem Log a obiektem Log wstrzykiwane do majątku mojego marvy małego obiektu Context są identyczne.

Jednak ...

Proces wtrysku wymagany że narazić właściwość Log obiektu Context poprzez interfejs, co oznacza, że ​​nie może już być statyczny obiekt. To, czy obiekt logognet ILog jest statyczny, wydaje się decydować o tym, czy jest on możliwy do serializacji, czy może być łączony między zespołami bez dramatycznych ostrzeżeń "runtime will not niestały" (które są naprawdę znaczące tylko dla fanów Matrix).

Zniechęcony, choć nie zniechęcony, użyłem "zręczności" Resharpera do właściwości z polem pomocniczym i ustawiłem pole podparcia na statyczne, podczas gdy właściwość interfejsu pozostała niestatyczna. Zbudowano go, a test przebiegł na zielono.

Więc nawet zrobiłem przebudowę i zadziałało. Więc może kiedy to się popsuje do testów integracyjnych, przekradnę się, że log4net nie jest serializowalnym fiaskiem.

Więc może to pomoże

Dzięki

Stato

+0

Nie jest normalną praktyką, aby rejestratory były zmiennymi instancji - są to zwykle zmienne statyczne (tj. Klasy) i są w każdym razie zaimplementowane jako single. Więc nie sądzę, żebyś odniósł jakąkolwiek korzyść, pobierając je z pojemnika Unity - dlaczego tak jest? –

+0

"dlaczego?" jest zdecydowanie rozsądnym pytaniem. Odpowiedź dotyczy pojedynczego punktu konfiguracji. używanie dowolnego rejestratora "wszędzie" staje się prawdziwym obciążeniem konfiguracji, a konserwacja jest ciężka w części "aint", jeśli chodzi o zabawę. –

Odpowiedz

5

Byłoby pomocą InjectionFactory w Unity 2 pomoc? (patrz this question). Następnie kod konfiguracja będzie wyglądać następująco:

IUnityContainer container = new UnityContainer(); 
container.RegisterType<ILog>(new InjectionFactory(factory => LogManager.GetLogger())); 

następnie je odzyskać rejestratora ze zwykłej rozmowy w celu rozwiązania():

ILog logger = container.Resolve<ILog>(); 
logger.Log(Level.Debug, "Hello world"); 

może także być w stanie skonfigurować żywotność rejestratora być również ContainerControllerLifetimeManager, aby uczynić go instancją typu singleton, ale jeszcze jej nie zweryfikowałem.

+0

jego wygląd podobny do log4net, ale użyteczny dla instancji obiektu, które są budowane również dla uruchamiania. dzięki. –

0
ILog logger = container.Resolve<ILog>(); 
logger.Log(Level.Debug, "Hello world"); 

rzeczywiście działa.

Jeśli jednak masz właściwość dla programu rejestrującego na klasie i chcesz wstawić do niej tę instancję rejestratora, to nie zadziała AFAICT. Myślę, że mogę być poza celem, ale próbuję ponownie użyć instancji programu rejestrującego w nowym kontekście. Może to być po prostu cofnąć, więc może będę musiał zrezygnować z wstrzykiwanie go i po prostu dodać linię

ILog logger = container.Resolve<ILog>(); 

do każdej klasy, która daje mi wynik wydaje się, że tylko nieznacznie różni się od uruchamianiu go w każdej klasie .. ..

miałem nadzieję, że

private ILog Logger {get;set;} 

może być po prostu wstrzykuje ale nie wydają się działać w ogóle, ponieważ przez cały log4net wszystko odbywa się za pośrednictwem interfejsów i beton rejestrator ukrywa się za zasłoną z Czarodziejem z krainy Oz.