Caliburn Micro和Castle Windsor Bootstrapper - 在Bootstrapper中注册View Model类

时间:2011-10-31 18:09:04

标签: wpf castle-windsor viewmodel caliburn.micro bootstrapping

我在我的WPF应用程序中使用Castle Windsor引导程序。我尝试将视图模型类注册到windsor容器。

我在名称空间sample.viewmodels中有所有视图模型类

所以我尝试了这个:

        _windsorContainer.Register(AllTypes.FromAssembly(GetType().Assembly)
                                       .Where(x => x.Namespace.EndsWith("ViewModels"))
                                       .Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));

或者这样将寄存器视图模型类转换为容器:

    _windsorContainer.Register(AllTypes.FromAssembly(GetType().Assembly)
                                   .Where(x => x.Namespace.Equals("Sample.ViewModels"))
                                   .Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));

这种方法不起作用。我不是为什么。 MainViewModel / ChildViewModel属性为null。

如果我使用这种风格,那就很好。

        ////Shell
        _windsorContainer.Register(
            Component.For<IShellViewModel>()
                .ImplementedBy<ShellViewModel>()
                .LifeStyle.Is(LifestyleType.Singleton));

        //Main screen
        _windsorContainer.Register(
            Component.For<IMainViewModel>()
                .ImplementedBy<MainViewModel>()
                .LifeStyle.Is(LifestyleType.Singleton));

        //Child screen
        _windsorContainer.Register(
            Component.For<IChildViewModel>()
                .ImplementedBy<ChildViewModel>()
                .LifeStyle.Is(LifestyleType.Singleton));

第一种情况有什么不好?

我在这里有视图模型:

namespace Sample.ViewModels
{
    public interface IShellViewModel
    {}

    public class ShellViewModel : Conductor<IScreen>.Collection.AllActive,
        IShellViewModel
    {
        public IMainViewModel MainViewModel { get; set; }

        public IChildViewModel ChildViewModel { get; set; }

        protected override void OnInitialize()
        {
            DisplayName = "Castle Windsor Boostraper";
            base.OnInitialize();
        }
    }

    public interface IMainViewModel : IScreen
    {
        void SayHello();
    }

    public class MainViewModel : Screen, IMainViewModel
    {
        public void SayHello()
        {
            MessageBox.Show("Hello from MainViewModel");
        }
    }
    public interface IChildViewModel : IScreen
    {
        void SayHello();
    }

    public class ChildViewModel : Screen, IChildViewModel
    {
        public void SayHello()
        {
            MessageBox.Show("Hello from ChildViewModel");
        }
    }
}

编辑:

我很少更新注册部分:

        _windsorContainer.Register(AllTypes.FromAssembly(GetType().Assembly)
                                       .Pick()
                                       .WithService.DefaultInterface()
                                       .Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));

它有效,但我不确定这是否是最佳方式。

2 个答案:

答案 0 :(得分:2)

我想你想做这样的事情来在Castle Windosr中注册你的视图模型

_windsorContainer.Register(AllTypes.FromThisAssembly()
    .Where(x => x.Namespace.EndsWith("ViewModels"))
    .WithService.AllInterfaces()
    .WithService.Self()
    .If(s => !s.IsAbstract)
    .Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));

但是我想知道为什么你将你的viewmodels注册为singleton?我会将它们注册为瞬态,因此您可以为应用程序中的同一视图实例化多个不同的视图模型。我还为我的viewmodels使用了一个marker-interface,所以我不必依赖于以“ViewModels”结尾的命名空间中的viewmodels。

_windsorContainer.Register(Classes
    .FromThisAssembly()
    .BasedOn<IViewModelBase>()
    .WithServiceAllInterfaces()
    .WithServiceSelf()
    .LifestyleTransient()

答案 1 :(得分:1)

在第一个示例中,您只注册具体类型为单例,第二个示例是将相关接口与实现相关联。由于您的属性将模型公开为接口,因此第一个代码部分将无法满足这些属性。