Windsor LifeStyle - 每个图形的共享实例

时间:2014-07-31 16:41:18

标签: c# wpf dependency-injection castle-windsor caliburn

我有两种类型的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;
          }  
      } 

我在Windsor Container注册了一项服务:

     public class Service : IService {}

     container.Register(Component.For<IService>()
                  .ImplementedBy<Service >().LifeStyle.Transient); 

我希望ViewModelA和ViewModelB共享同一个IService实例。

不要让ViewModelA和ViewModelB的所有实例共享同一个实例。

每个父/子对都有自己的实例,我不想使用DependencyInjection来实现这一点吗?

我希望通过依赖注入完成此操作,因为我在A下有一个完整的ViewModel层次结构,而不仅仅是一个(B)视图模型。

VM A - &gt; VM B - &gt; VM C - &gt; VM D ...(并且让我们说错了所有字母表)所有这些都需要共享同一个IService实例。

和A的另一个实例和它的死者将共享一个不同的IService实例。

2 个答案:

答案 0 :(得分:4)

您可以使用 Scoped Lifestyles 。以下是一些单元测试的示例,它们似乎可以满足您的需求:

[Fact]
public void VMsInSameScopeSharesService()
{
    var container = new WindsorContainer();
    container.Register(Component.For<ViewModelA>().LifestyleTransient());
    container.Register(Component.For<ViewModelB>().LifestyleTransient());
    container.Register(Component
        .For<IService>().ImplementedBy<NullService>().LifestyleScoped());

    using (container.BeginScope())
    {
        var a = container.Resolve<ViewModelA>();

        Assert.Equal(a.service, a.childViewModel.service);
    }
}

[Fact]
public void VMsInDifferentScopesDoNotShareServices()
{
    var container = new WindsorContainer();
    container.Register(Component.For<ViewModelA>().LifestyleTransient());
    container.Register(Component.For<ViewModelB>().LifestyleTransient());
    container.Register(Component
        .For<IService>().ImplementedBy<NullService>().LifestyleScoped());

    IService service1;
    using (container.BeginScope())
    {
        var a = container.Resolve<ViewModelA>();

        service1 = a.service;
    }
    IService service2;
    using (container.BeginScope())
    {
        var a = container.Resolve<ViewModelA>();

        service2 = a.service;
    }

    Assert.NotEqual(service1, service2);
}

然而,这是一个非常奇特的要求,这让我想知道为什么你希望它的行为完全像这样,或者如果你不能以一种简化代码的方式构建你的代码。

答案 1 :(得分:4)

对我有用的是:LifeStyle BoundTo

    container.Register(Component.For<IService>()
            .ImplementedBy<Service>()
            .LifeStyle.BoundTo<ViewModelA>());

图表:

     public class ViewModelAConductor 
     {
         private List<ViewModelA> rootViewModels = new List<ViewModelA>();
         public ViewModelAConductor()
         {
              ViewModelA a1 = container.Resolvce<ViewModelA>(); 
              rootViewModels.Add(a1);

              ViewModelA a2 = container.Resolvce<ViewModelA>(); 
              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;                 
          }               
     }  

a1 图表下注入的所有ViewModel都具有相同的IService实例。

a2 图表下注入的所有ViewModel都具有相同的IService实例。