Reputation: 8428
I can't figure this one out. I have a WPF application using the MVVM pattern with Unity constructor dependency injection. In the application, I use a custom control. All was well at first: I added the control to my main window and it displayed in the VS designer just fine. Then I wanted the control to do something useful, and to do so, it needed a data provider. I decided that the best way to provide that was to add the provider as a dependency in the constructor.
That's when everything went south. Although the program runs as expected, the VS designer can't instantiate the control. I've built a simple application to illustrate my dilemma.
MainWindow code behind:
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();
}
}
}
MainWindow 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>
App code behind:
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());
}
}
}
I think the problem is that the VS designer doesn't know to register the IDependency type before newing up the control. Am I correct? Is there way around this?
I'm using VS 2010 Ultimate and .Net 4.0.
Upvotes: 0
Views: 895
Reputation: 30391
The VS designer will try to call a zero-argument constructor using new to create the control in the designer; it knows nothing about and will not try to resolve through your container. In addition, your App.Unity property is not available to the designer, nor has setup code run.
Your best best to to change your control's constructor to use a stubbed out design time only data provider instead of trying to resolve through the container when using that constructor.
Upvotes: 0