使用IoC的WPF Designer加载失败

时间:2012-07-13 17:34:26

标签: c# wpf mvvm ioc-container tinyioc

我有一个相当简单和标准的MVVM WPF应用程序。我使用TinyIoC作为容器来为ViewModel提供底层数据和缓存提供程序。我正在使用TinyIoC,因为我还希望与MonoTouch和Monodroid项目共享此代码。

每个用户控件的ViewModel都不依赖于从TinyIoC解析数据提供程序,它们在添加到MainWindow的XAML时工作正常。

用户控制哪些ViewModel正在使用TinyIoC来解析所使用的数据提供程序获取其数据,在添加到MainWindow时无法在设计器视图中实例化。

重要提示:当我运行应用程序时,一切正常,只是设计师被打破 - 这是一个很大的障碍。

以下是基本代码:

    // From App.xaml.cs
    private void HandleAppStartupEvent(object sender, StartupEventArgs e) {
        IDataStoreProvider store = new XmlDataStoreProvider();
        ICacheProvider cache = new DictionaryCacheProvider();

        TinyIoCContainer.Current.Register(store);
        TinyIoCContainer.Current.Register(cache);
    }

View / ViewModel / XAML绑定标准实现 - 这里没什么问题。

在数据层的深处,IoC容器用于解析使用哪个提供程序 - 在上面的代码中设置的提供程序。

public static class Gateway
{
    private static IDataStoreProvider store;
    private static ICacheProvider cache;

    static Gateway() {
        store = TinyIoCContainer.Current.Resolve<IDataStoreProvider>();
        cache = TinyIoCContainer.Current.Resolve<ICacheProvider>();
    }

    // use the store and cache here...

}

以下是我从设计师那里得到的确切错误。

  

无法解析类型:Sample.Core.Data.IDataStoreProvider      在TinyIoC.TinyIoCContainer.ResolveInternal(TypeRegistration注册,NamedParameterOverloads参数,ResolveOptions选项)中的C:_dev \ Sample \ SampleSolution \ Sample.Core \ Utility \ TinyIoC.cs:line 3281      at TinyIoC.TinyIoCContainer.Resolve(Type resolveType)在C:_dev \ Sample \ SampleSolution \ Sample.Core \ Utility \ TinyIoC.cs:第1314行      at TinyIoC.TinyIoCContainer.ResolveResolveType in C:_dev \ Sample \ SampleSolution \ Sample.Core \ Utility \ TinyIoC.cs:line 1433      at C:_dev \ Sample \ SampleSolution \ Sample.Core \ Data \ Gateway.cs中的Sample.Core.Data.Gateway..cctor():第14行

我想我理解为什么会出现这个错误 - 在设计器加载并在MainWindow中执行用户控件之前,不会触发App启动事件来加载IoC。

同样值得注意的是,该应用程序运行良好 - IoC和一切。我想停止设计器加载错误(按优先顺序):

  • 了解如何修复代码以正确使用设计器
  • 使用设计师的模拟数据存档现有的控制数据
  • 禁用此设计器功能

2 个答案:

答案 0 :(得分:0)

您是否尝试在Windows /容器加载事件的事件处理程序中加载数据?这样做过去给我造成了这类问题。

答案 1 :(得分:0)

这是第二个项目符号的解决方案(用设计师的模拟数据存取现有的控制数据)

将以下代码添加到ViewModel构造函数中:

    public AdminViewModel(UserControl view) {
        this.view = view;

        var designMode = DesignerProperties.GetIsInDesignMode(view);

        if (designMode) {
            Items = new ObservableCollection<ItemModel>
                      {new ItemModel {Name = "Item1"}, 
                       new ItemModel {Name = "Item2"}};
        }
        else {
            Items= new ObservableCollection<ItemModel>(Gateway.GetItems());
        }   
    }

虽然有效但我有几个问题:

  • 使用非app逻辑污染代码
  • 强制我将View的引用传递给ViewModel

我更愿意以更清洁的方式使这更“混合”和设计师友好 - 任何其他想法?