2010-06-10 11 views
6

W nowym projekcie WPF (VS2010) używam Unity 2 po raz pierwszy. W tym projekcie używam następującą strukturę:Jak rozwiązywać problemy przy użyciu Unity w rozwiązaniu z wieloma projektami

rozwiązanie

WPF Projekt

Klasa Library1

Klasa Library2

Class Library 3 ....

rejestracji różne typy wykorzystujące Unity są wykonywane w Projekcie WPF przy użyciu następującego fragmentu:

IUnityContainer container = new UnityContainer() 
          .RegisterType<IObjectContext, ObjectContextAdapter>() 
          .RegisterType<IConnectionStringProvider, ConnectionStringProvider>() 
          .RegisterType(typeof(IRepository<>), typeof(Repository<>)); 

Załóżmy teraz, że chciałbym, aby repozytorium <Orders> constructor-injected zostało rozwiązane w bibliotece Class1. Najwyraźniej kontener nie jest znany w innych projektach!

Jak to zrobić?

Odpowiedz

9

W większości zgadzam się z odpowiedzią Chrisa, ale myślę, że pliki konfiguracyjne są icky (szczególnie dla Unity), więc oto rozwiązanie, które pozwoli ci użyć konfiguracji runtime bez okrągłych odnośników. Zamierzamy to zrobić z rejestrami.

Utwórz projekt infrastruktury, który będzie zawierał IConfigureUnity.

public interface IConfigureUnity 
{ 
    public void Configure(UnityContainer container); 
} 

Każdy projekt biblioteki klas będzie odpowiedzialny za implementację tego interfejsu w celu zarejestrowania własnych klas.

public class RegistryForSomeClassLibrary : IConfigureUnity 
{ 
    public void Configure(UnityContainer container) 
    { 
     container 
      .RegisterType<IObjectContext, ObjectContextAdapter>() 
      .RegisterType<IConnectionStringProvider, ConnectionStringProvider>() 
      .RegisterType(typeof(IRepository<>), typeof(Repository<>)); 
    } 
} 

Następnie w projekcie WPF należy utworzyć kontener i zastosować te rejestry.

var container = new UnityContainer(); 
new RegistryForSomeClassLibrary().Configure(container); 
new RegistryForAnotherClassLibrary().Configure(container); 

Teraz masz w pełni skonfigurowaną instancję kontenera bez plików konfiguracyjnych.

+0

Załóżmy, że mam okno dialogowe w bibliotece klas 1 o nazwie "ManageUser". W jaki sposób ManageUser pobiera wystąpienie kontenera zadeklarowanego w projekcie WPF? –

+1

@Ryan - Czy jest jakiś powód, aby używać interfejsu we wspólnym projekcie? Dlaczego nie uczynić klasy Registry i Configure zarówno statyczną, jak i wywołać w ten sposób: 'RegistryForSomeClassLibrary.Configure (container); RegistryForAnotherClassLibrary.Configure (kontener); 'Testowałem to i działa. Czy czegoś brakuje? – Shevek

+0

@Shevek, To działa dobrze. Kiedyś rozwiązywałem swoje rejestry, korzystając z refleksji, ale zrezygnowałem z tego czasu. Teraz jawnie nazywam 'Configure()' na każdym rejestrze. – Ryan

0

Aby wiele projektów korzystało z tego samego UnityContainer w tym scenariuszu, potrzebny jest "wspólny" projekt, który zawiera UnityContainer i udostępnia go tak, aby wszystkie inne projekty mogły uzyskać do niego dostęp.

tj

WPF Projekt

Class Library 1

Class Library 2

Class Library 3

Common Library (UnityContainer mieszka tutaj)

Aby uniknąć okrągły zależności projektu , Zalecam używanie Unity design-time configuration via a configuration file zamiast konfiguracji czasu wykonywania (jak w twoim przykładzie). W przeciwnym razie Twoja biblioteka wspólna będzie musiała odwoływać się do projektów, które zawierają wszystkie typy, które on rozwiązuje, a te projekty z kolei będą zależne od wspólnej biblioteki (ponieważ prawdopodobnie jest to miejsce, w którym można narazić instancję UnityContainer). Możesz być w stanie uruchomić go przy użyciu konfiguracji czasu, ale tego nie próbowałem; Wiem, że konfiguracja czasu projektowania działa tak, jak ja wykonałem kilka projektów przy użyciu dokładnie takiego modelu.

+0

Dzięki Chris, spróbuję! –