2016-02-07 55 views
5

Mam dużą aplikację wpf. Upraszczam mój problem z autofac. Powiedzmy, że mam ViewModelLocator, gdzie tworzę contrainer. ViewModelLocator jest w projekcie Company.WPF, projekt ten odnosi się do projektu Company.ViewModels.Użyj autofac w wielu rozwiązaniach projektowych

var builder = new ContainerBuilder(); 
builder.RegisterType<MainWindowViewModel>().AsSelf().SingleInstance(); 
container = builder.Build(); 

Problem: MainWindowViewModel potrzebuje ICompanyService (używam CI), który jest w projekcie Company.Services, projekt ten nie powinien być referencyjny Company.WPF. Usługa ICompanyService jest publiczna iw tym samym projekcie (Company.Services) jest również implementacją CompanyService, ale jest tylko wewnętrzna.

Jak mogę ustawić Autofac dla tych? Zwykle używam castela Wisndora, w tej sytuacji są instalatorzy, czy w Autofac jest taka sama opcja?

Odpowiedz

5

Poszukujesz pojęcia Modules w autofac. Dla każdej warstwy w twojej architekturze dodajesz nowy moduł autofac dla tej warstwy, gdzie rejestrujesz typy tej warstwy. W swoim ViewModelLocator, w którym budujesz swój autofac kontener, wystarczy zarejestrować moduły autofac zamiast rejestrować wszystkie typy bezpośrednio.

Bardziej szczegółowo i w Twoim przypadku może to wyglądać mniej więcej tak:

W projekcie Company.Services:

dodać nowy moduł ServicesModule z czymś takim. :

public class ServiceModule : Autofac.Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
    // optional: chain ServiceModule with other modules for going deeper down in the architecture: 
    // builder.RegisterModule<DataModule>(); 

    builder.RegisterType<CompanyService>().As<ICompanyService>(); 
    // ... register more services for that layer 
    } 
} 

W projekcie Company.ViewModels:

również utworzyć ViewModelModule gdzie można zarejestrować wszystkie swoje ViewModels podobne do ServiceModule.

public class ViewModelModule : Autofac.Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
    // in your ViewModelModule we register the ServiceModule 
    // because we are dependent on that module 
    // and we do not want to register all modules in the container directly 
    builder.RegisterModule<ServiceModule>(); 

    builder.RegisterType<MainViewModel>().AsSelf().InSingletonScope(); 
    // ... register more view models 
    } 
} 

w projekcie (ViewModelLocator) Company.Wpf:

var builder = new ContainerBuilder(); 
builder.RegisterModule<ViewModelModule>(); 
builder.Build(); 

Zauważ, że skoro zarejestrował ServiceModule w ViewModelModule, po prostu musimy zarejestrować ViewModelModule bezpośrednio w ContainerBuilder. Ma to tę zaletę, że nie trzeba dodawać odwołania do projektu Company.Service w projekcie Company.Wpf.