2011-08-22 22 views
7

Przygotowuję moje pliki konfiguracyjne xml dla mojej aplikacji internetowej asp.net za pomocą iniekcji zależności spring.net IOC. Odwołuję się do każdego z moich plików konfiguracyjnych w pliku web.config. Przykładem ustawienia w pliku konfiguracyjnym Spring.net (settings.xml) jest:redefiniować obiekt spring.net w wielu plikach konfiguracyjnych

<object id="obj1" 
     type="NS.Common.Cache.Class, NS.Common" 
     singleton="true" 
     init-method="Initialize" 
     destroy-method="Dispose"> 
    <property name="Name" value="My Name" /> 
</object> 

To wszystko działa bez zarzutu.

Teraz instaluję aplikację internetową w wielu środowiskach, dlatego tworzę plik konfiguracyjny spring.net dla środowiska, np. dev, qa, prod.

Podczas instalowania aplikacji odpowiedni plik sprężyny środowiska jest wymieniony w pliku web.config. Jest to część automatycznego instalatora.

w pliku środowiska QA, chcę przedefiniować obiekt nad „obj1” do:

<object id="obj1" 
    type="NS.Common.Cache.Class2, NS.Common" 
    singleton="true" 
    init-method="Initialize" 
    destroy-method="Dispose"> 
    <property name="Name" value="My New Name" /> 
</object> 

Jednak jak to jest zautomatyzowane (dodanie odniesienia do pliku środowiska), plik jest settings.xml nie zmieniony.

A teraz odniesienie do 2 plików o zdefiniowanym obiekcie o tym samym id - powoduje to poważne problemy, ponieważ wystąpią błędy czasu wykonywania.

Czy istnieje sposób, w jaki mogę uwzględnić w qa.xml i flagi lub tym podobne, aby podświetlić tę definicję obiektu nadpisuje inne zdefiniowane obiekty w dowolnym innym pliku xml o tym samym id obiektu?

+1

Można załadować dwa identyczne identyfikatory, co spowoduje "przesłonięcie" pierwszego wyświetlonego obiektu (przed utworzeniem, AFAIK muszą znajdować się w różnych plikach, poprzez odwołanie się do nich przez . Z tego powodu jest to dobre przećwicz swoje zasoby kontekstowe w kolejności zaczynającej się od "globalnego znaczenia" aż do "lokalnego znaczenia" (z ustawieniem app.config przy ostatnim wpisie) – Beachwalker

+2

@Stegi : dlaczego nie podać tego jako odpowiedzi? Wygląda na to, że rozwiązuje to problem z OP: – Marijn

+1

W pliku * single * xml "identyfikator" można podać tylko raz.Atrybut 'id' w rzeczywistości jest atrybutem xml - więc parser xml zapewnia dodatkową weryfikację zarówno w Visual Studio, jak i podczas ładowania pliku w środowisku wykonawczym. Ale jak wspomina Stegi, możesz określić obiekt o tym samym id w różnych plikach, załadowany tym samym kontekstem. Definicja z ostatnio załadowanego pliku zastępuje wszelkie poprzednie definicje tym samym identyfikatorem. – Marijn

Odpowiedz

1

Zamiast definiowania obiektów o tym samym identyfikatorze (co nie jest możliwe, jak już wspomniano Marijin), można zdefiniować alias w pliku konfiguracyjnym, który można kontrolować.

E.g. można mieć

<object name="ProdObj1" type="NS.Common.Cache.Class, NS.Common" singleton="true"> 
    <property name="Name" value="Prod" /> 
</object> 

i

<object name="TestObj1" type="NS.Common.Cache.Class, NS.Common" singleton="true"> 
    <property name="Name" value="Test" /> 
</object> 

a następnie użyć

<alias name="ProdObj1" alias="obj1"/> 

w, na przykład, swój web.config.

+0

To będzie działać tylko wtedy, gdy możesz zmienić 'settings.xml', mianowicie zmienić nazwę' obj1' na 'ProdObj1'. Od pytania rozumiem, że OP chce tego uniknąć. Może to być przydatna technika - w rzeczywistości może to być sposób na wykonanie scenariusza OP - ale wymagałoby to zmiany 'settings.xml'. – Marijn

+0

jak masz na myśli zmianę pliku settings.xml? – amateur

+0

Twój scenariusz, ponieważ go nie używam: z pierwszego akapitu przeczytałem, że "obj1" jest zdefiniowany w pliku "settings.xml" jako prawidłowość? ten plik ustawień jest wdrażany w twoich środowiskach qa i produkcyjnych. Zarówno w qa, jak i w produkcji, odwołujesz się do pliku settings.xml, który (z jakiegoś nieokreślonego powodu) nie można zmienić. Zatem zarówno przy produkcji, jak i qa, "obj1" jest obiektem zdefiniowanym w pliku settings.xml. – Marijn

6

Można załadować dwa identyczne identyfikatory, a ostatni identyfikator "zastąpi" pierwszy wymieniony obiekt (przed utworzeniem muszą one znajdować się w różnych plikach, ponieważ mają odwołania do definicji kontekstu).

<context ...> 
    <resource ... /> <!-- put your 3rd-party (read-only config here) --> 
    <resource ... /> <!-- put your override ids here --> 
</context> 

powodu tej domyślnym zachowaniem jest to dobra praktyka, aby to swoje ressources kontekstu, w kolejności literę „globalnego znaczenia” (np 3rd configs partyjnych chcesz ponownie użyć) w dół do „lokalnym znaczeniu” (o aplikacji .config jest jako ostatni wpis).