Caliburn.Micro + Unity 2.1 + MVVM:示例代码

时间:2013-05-26 14:11:33

标签: mvvm dependency-injection inversion-of-control unity-container caliburn.micro

我正在尝试在WPF MVVM应用程序中实现Unity,但我错过了大局。

此刻我创建了一个这样的引导程序:

  public class MainBootstrapper : Bootstrapper<MainViewModel>
  {
    private UnityContainer container;

    protected override void Configure()
    {
      container = new UnityContainer();
      container.RegisterType<IServiceLocator, UnityServiceLocator>(new ContainerControlledLifetimeManager());
      container.RegisterType<IWindowManager, WindowManager>(new ContainerControlledLifetimeManager());
      container.RegisterType<IEventAggregator, EventAggregator>(new ContainerControlledLifetimeManager());
    }

    protected override object GetInstance(Type service, string key)
    {
      if (service != null)
      {
        return container.Resolve(service);
      }

      if (!string.IsNullOrWhiteSpace(key))
      {
        return container.Resolve(Type.GetType(key));
      }

      return null;
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
      return container.ResolveAll(service);
    }

    protected override void BuildUp(object instance)
    {
      container.BuildUp(instance);
    }
  }

使用它的最佳方法是什么? 此代码目前有效:

  public class MainViewModel : PropertyChangedBase
  {
    public MainViewModel()
    { }

    [Dependency]
    public Sub1ViewModel Sub1VM { get; set; }
    [Dependency]
    public Sub2ViewModel Sub2VM { get; set; }
  }

MainView有这个:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <ContentControl Grid.Row="0" Name="Sub1VM" />
    <ContentControl Grid.Row="1" Name="Sub2VM" />

</Grid>

首先:我分享的代码,这是使用Unity + Caliburn的正确方法吗?

现在让我们说我的Sub1VM使用模型'M1',但是Sub2VM需要使用相同的模型来显示信息,而不是通过创建模型M1的另一个实例。 (singleton)的

现在如何运作?显示我在每个viewmodel构造函数中使用IServiceLocator?有人可以分享一个代码示例来解释它吗?

2 个答案:

答案 0 :(得分:1)

我并不特别了解Unity,但您的配置看起来是正确的。

至于你的注射点。我会说,不应该进行属性注入,而应该进行构造函数注入。你正在做的很好,但是你可能想要查看屏幕和导体,这些允许你为ViewModel添加生命周期。通常它看起来像这样:

  • Bootstrapper打开ShellViewModel

  • ShellViewModel通过Ctor注入接收MainViewModel作为IConductorOneActive

  • MainViewModel采用了一系列IScreens。

  • ShellViewModel在MainViewModel上调用MainViewModels激活方法。

Screens, Conductors and Composition。正如我上面所说,你的方式很好,但它在手动方面有一点意味着你必须手工连接所有东西。

答案 1 :(得分:1)

首先,我同意McDonnellDean你应该阅读关于屏幕,指挥和作文的文章(如果我是你,我会在此之前阅读所有文章,以了解Caliburn.Micro如何工作。)< / em>的。除此之外,您正确实现了Unity,您可以查看Unity as IoC Container for Caliburn.Micro以获取更多信息。另一方面,您在这里混合了两个概念,即依赖注入和MVVM。关于你关于模型的问题,我也更喜欢构造函数注入,如果你想要一个模型的单个实例,也许你可以注入一个为你创建该模型的Factory并将其包装到两个不同的视图模型中通过两个不同的属性公开它。最后,我非常鼓励您阅读教程(start here),至少是基本主题。