【问题标题】:Custom control with constructor dependency not loading in VS designer具有构造函数依赖项的自定义控件未在 VS 设计器中加载
【发布时间】:2012-11-16 04:29:07
【问题描述】:

我想不出来这个。我有一个 WPF 应用程序,它使用带有 Unity 构造函数依赖注入的 MVVM 模式。在应用程序中,我使用了自定义控件。一开始一切都很好:我将控件添加到我的主窗口,它在 VS 设计器中显示得很好。然后我想让控件做一些有用的事情,而要做到这一点,它需要一个数据提供者。我认为最好的方法是将提供者添加为构造函数中的依赖项。

那是一切都向南的时候。尽管程序按预期运行,但 VS 设计器无法实例化控件。我构建了一个简单的应用程序来说明我的困境。

MainWindow 后面代码:

using System.Windows;
using System.Windows.Controls;
using Microsoft.Practices.Unity;

namespace DependencyInjectionDesigner
{
    public interface IDependency { }

    class Dependency : IDependency { }

    class DependentControl : Control
    {
        public DependentControl()
            : this(App.Unity.Resolve<IDependency>()) { }
        public DependentControl(IDependency dependency) { }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

主窗口 XAML:

<Window x:Class="DependencyInjectionDesigner.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DependencyInjectionDesigner"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type local:DependentControl}">
            <Setter Property="Margin" Value="30"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:DependentControl}">
                        <Border BorderBrush="Green" Background="Gainsboro"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <local:DependentControl/>
    </Grid>
</Window>

应用程序代码:

using System.Windows;
using Microsoft.Practices.Unity;

namespace DependencyInjectionDesigner
{
    public partial class App : Application
    {
        public static IUnityContainer Unity { get; private set; }

        protected override void OnStartup(StartupEventArgs e)
        {
            if (Unity != null) return;
            Unity = new UnityContainer();
            Unity.RegisterType<IDependency, Dependency>(
                new ContainerControlledLifetimeManager());
        }
    }
}

我认为问题在于 VS 设计者在更新控件之前不知道要注册 IDependency 类型。我对么?有办法解决吗?

我正在使用 VS 2010 Ultimate 和 .Net 4.0。

【问题讨论】:

    标签: wpf dependency-injection unity-container


    【解决方案1】:

    VS 设计器将尝试使用 new 调用零参数构造函数来在设计器中创建控件;它一无所知,也不会尝试通过您的容器解决。此外,您的 App.Unity 属性对设计器不可用,设置代码也无法运行。

    最好将控件的构造函数更改为使用仅存根的设计时数据提供程序,而不是在使用该构造函数时尝试通过容器解析。

    【讨论】:

    • 我将您的答案标记为您的答案,因为您是唯一一个愿意回答我的问题的人。最后,我选择对控件的依赖项使用属性注入,这似乎工作得很好。在我看来,仍然应该有一种本地方式来配置设计器以使用 Unity,但也许这只是一个愿望。
    • 我也在考虑这个。我现在在 WinRT Xaml 中工作,我几乎没有需要放在可移植库中的自定义控件。这意味着它不应该依赖于设备特定的 dll。现在我的一些控件处理特定于设备的类,例如剪贴板。这就是为什么我需要对一些自定义控件(例如自定义文本框)进行 DI。这有什么好运气吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2012-10-30
    • 2019-07-12
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    相关资源
    最近更新 更多