2016-02-07 32 views
5

Ho una grande applicazione wpf. Semplifico il mio problema con autofac. Diciamo che ho ViewModelLocator dove creo contrainer. ViewModelLocator è nel progetto Company.WPF, questo progetto fa riferimento al progetto Company.ViewModels.Usa autofac in più soluzioni di progetto

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

Problema: MainWindowViewModel bisogno ICompanyService (io uso CI) che è in progetto Company.Services, questo progetto non dovrebbe essere di riferimento da Company.WPF. ICompanyService è pubblico e nello stesso progetto (Company.Services) è anche implementazione CompanyService, ma è solo interno.

Come è possibile impostare Autofac per questi? Di solito uso castel Wisndor, ci sono installatori per queste situazioni, è un'opzione simile anche in Autofac?

risposta

5

Stai cercando il concetto di Modules in autofac. Per ogni livello della tua architettura aggiungi un nuovo modulo autofac per quel livello, in cui registri i tipi di quel livello. Nel tuo ViewModelLocator, dove costruisci il tuo contenitore di autofac, devi solo registrare i moduli di autofac invece di registrare tutti i tipi direttamente.

Più in dettaglio e per il vostro caso questo potrebbe essere simile a questa:

Nel progetto Company.Services:

Si aggiunge un nuovo modulo ServicesModule con qualcosa di simile. :

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 
    } 
} 

Nel progetto Company.ViewModels:

È inoltre possibile creare un ViewModelModule in cui si registra tutti i tuoi ViewModels simili al 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 
    } 
} 

Nel Company.Wpf progetto (ViewModelLocator):

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

Nota che da quando abbiamo registrato il ServiceModule all'interno del ViewModelModule, non ci resta che registrare il ViewModelModule direttamente nel ContainerBuilder. Questo ha il vantaggio di non dover aggiungere un riferimento al progetto Company.Service all'interno del progetto Company.Wpf.