Windsor LifeStyle – Instance partagée par graphique

J’ai 2 types de ViewModel

public class ViewModelA { IService service; private ViewModelB childViewModel; public ViewModelA(IService service,ViewModelB childViewModel) { this.service = service; this.childViewModel = childViewModel; } public ViewModelB ChildViewModel { get { return childViewModel; } } } public class ViewModelB { IService serivce; public ViewModelB(IService service) { this.service = service; } } 

J’ai un service enregistré dans un conteneur Windsor:

  public class Service : IService {} container.Register(Component.For() .ImplementedBy().LifeStyle.Transient); 

Je souhaite que ViewModelA et ViewModelB partagent la même instance d’IService.

Je ne souhaite pas que toutes les instances de ViewModelA et ViewModelB partagent la même instance.

Chaque paire parent / enfant aurait sa propre instance, je ne voudrais pas y parvenir en utilisant DependencyInjection, cela peut-il être fait?

Je ne voudrais pas que cela se fasse par l’dependency injection, car j’ai toute une hiérarchie de ViewModels sous A et non pas un (B) viewmodel.

VM A -> VM B -> VM C -> VM D … (et disons que je ne vais pas parcourir l’alphabet), tous ces éléments doivent partager la même instance d’IService.

et une autre instance de A et ses descendants partageraient une instance différente de IService.

Vous pourrez peut-être utiliser des styles de vie ciblés . Voici un exemple de tests unitaires qui semblent faire ce que vous voulez:

 [Fact] public void VMsInSameScopeSharesService() { var container = new WindsorContainer(); container.Register(Component.For().LifestyleTransient()); container.Register(Component.For().LifestyleTransient()); container.Register(Component .For().ImplementedBy().LifestyleScoped()); using (container.BeginScope()) { var a = container.Resolve(); Assert.Equal(a.service, a.childViewModel.service); } } [Fact] public void VMsInDifferentScopesDoNotShareServices() { var container = new WindsorContainer(); container.Register(Component.For().LifestyleTransient()); container.Register(Component.For().LifestyleTransient()); container.Register(Component .For().ImplementedBy().LifestyleScoped()); IService service1; using (container.BeginScope()) { var a = container.Resolve(); service1 = a.service; } IService service2; using (container.BeginScope()) { var a = container.Resolve(); service2 = a.service; } Assert.NotEqual(service1, service2); } 

Cependant, il s’agit là d’une exigence assez exotique, ce qui m’amène à me demander pourquoi vous voulez qu’il se comporte exactement comme cela ou si vous ne pouvez pas structurer votre code de manière à simplifier les choses.

Ce qui a fonctionné pour moi, c’est: LifeStyle BoundTo

  container.Register(Component.For() .ImplementedBy() .LifeStyle.BoundTo()); 

Graphique :

  public class ViewModelAConductor { private List rootViewModels = new List(); public ViewModelAConductor() { ViewModelA a1 = container.Resolvce(); rootViewModels.Add(a1); ViewModelA a2 = container.Resolvce(); rootViewModels.Add(a2); } } public class ViewModelA { ViewModelB viewModelB; IService service; public ViewModelA(IService service,ViewModelB viewModelB) { this.service = service; this.viewModelB = viewModelB; } } public class ViewModelB { ViewModelC viewModelC; IService service; public ViewModelA(IService service,ViewModelC viewModelC) { this.service = service; this.viewModelC = viewModelC; } } public class ViewModelC { IService service; public ViewModelA(IService service) { this.service = service; } } 

Tous les ViewModels injectés sous le graphique de a1 ont la même instance d’IService.

Tous les ViewModels injectés sous le graphique de a2 ont la même instance d’IService.