0

我正在使用 MVVM 模式 + 一个简单的 ServiceLocator 实现,现在我的问题是当视图在设计时运行时我应该如何设置服务?

我试过了,但它似乎在 VS 2010 或某些东西上不起作用,我知道它在我的旧电脑上工作,但在我的新电脑上却不行。那么有人知道一个好的选择吗?

编辑:(代表 Merlyn Morgan-Graham)

好吧,我想做的是这个,我有我的观点,ViewModel 和服务现在不同的是,我有每个服务的 2 个实现,一个用于设计时,一个用于运行时。为了更好的解释看这里

4

3 回答 3

1

如果您想将视图与视图模型分离,并将视图模型与模型/dal 分离(基本上,如果您想使用 MVVM),那么您的视图模型和数据模型不应该对设计时间有任何了解。设计时间仅适用于视图。

本文展示了一种通过 XML/XAML 定义设计时数据的方法,因此您的代码无需了解任何相关信息:

http://karlshifflett.wordpress.com/2009/10/21/visual-studio-2010-beta2-sample-data-project-templates/

编辑后:事实证明,您仍然必须使用视图模型才能使现有的 XAML 绑定正常工作。这只会填充视图模型,而不必创建新的数据模型。我不确定,但可能有一些类允许您使用 WPF 绑定机制来处理这个...视图?

Resume Before Edit...:就您首先链接的文章中的解决方案而言,设计器除了您的类及其引用的代码外,不会实例化任何东西。这意味着除非您的视图代码以某种方式直接引用它们,否则不会实例化程序集属性。

如果您真的想在设计时将您的视图模型耦合到您的视图,并使其注册设计时服务,那么您必须将服务注册代码放在您的视图类中,或者视图类直接引用的类中。

为此,您可以使用视图的静态构造函数来注册设计时服务。您还可以在其他一些类(应用程序?)上编写一个静态方法来(有条件地)注册设计时服务。然后,在视图的构造函数中调用该方法。

或者您可以简单地在每个视图的构造函数中注册它们。

基本上,您想做的事情是可能的,但第一篇文章中链接的方法不是。如果您在评论中进一步阅读,您会发现他的方法被打破了。

您可能还想质疑在设计时将视图模型与视图挂钩的想法,因为 MVVM 模式旨在避免这种事情。

于 2010-08-16T03:02:58.247 回答
0

您通常不需要在设计时访问服务...通常,您甚至不会在设计时使用真实的 ViewModel,而是使用虚拟设计数据,如此所述。如果您真的需要使用真实的 ViewModel,您可以实现服务的虚拟版本,并使用它们代替真实的服务:

if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
    // Design time
    ServiceLocator.Instance.Register<IService1>(new DummyService1());
    ServiceLocator.Instance.Register<IService2>(new DummyService2());
}
else
{
    // Run time
    ServiceLocator.Instance.Register<IService1>(new RealService1());
    ServiceLocator.Instance.Register<IService2>(new RealService2());
}
于 2010-08-15T21:25:23.843 回答
0

此外,我同意所有对在设计时使用服务定位器有疑虑的人,我相信这在某些用例中是有效的场景。这不是关于为什么/为什么不的讨论,这是它(几乎)为我工作的简单方式。还有一个问题我还没有解决:这一次只适用于一个视图。

  1. 创建一个简单的引导程序来设置您选择的 IoC。注意 ISupportInitialize 接口。

    public class Bootstrapper: ISupportInitialize
    {
        #region ISupportInitialize Members
    
        public void BeginInit() { }
    
        public void EndInit()
        {
            if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
                Setup();
        }
    
        #endregion
    
        public static void Setup() { SetupServiceLocator(); }
    
        static void SetupServiceLocator()
        {
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<ConfigService>().As<IConfigService>().ExternallyOwned().SingleInstance();
            IContainer container = builder.Build();
    
            ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(container));
        }
    }
    
  2. 像以前一样在运行时模式下使用引导程序,例如:

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            Bootstrapper.Setup();
        }
    }
    
  3. 此外,您需要将其添加到应用程序资源以支持设计模式:

    <Application x:Class="MonitoringConfigurator.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:MyBootstrapperNamespace"
                 StartupUri="MainWindow.xaml">
        <Application.Resources>
            <local:Bootstrapper x:Key="Bootstrapper" />
        </Application.Resources>
    </Application>
    
于 2014-12-03T14:03:40.383 回答