WPF 依赖注入
WPF Dependency injection
您好,我在 WPF 应用程序中遇到依赖注入问题。这是我的代码:
App.xaml.cs:
IUnityContainer container = new UnityContainer();
container.RegisterType<ICarViewModel, CarViewModel>();
container.RegisterType<MainWindow>();
MainWindow mainWindow = container.Resolve<MainWindow>();
mainWindow.Show();
CarViewModel.cs:
public ObservableCollection<Car> Cars{ get; } = new ObservableCollection<Car>()
{
new Car() {Name = "Audi"},
new Car() {Name = "Peugeot"},
new Car() {Name = "Renault"},
};
CarView.cs:
public partial class CarView : UserControl, ICarView
{
public CarView()
{
InitializeComponent();
}
public CarView(CarViewModel carViewModel) : this()
{
DataContext = carViewModel;
}
}
CarView.xaml:
<ItemsControl ItemsSource = "{Binding Path = Cars}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBlock Text = "{Binding Path = Name, Mode = OneWay}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
MainWindow.xaml:
<view:CarView x:Name = "CarViewControl"></view:CarView>
Unity 容器仍然只从 CarView 调用没有参数的构造函数。
谢谢指教
您可以这样注册类型:
container.RegisterType(typeof(MainWindow), typeof(MainWindow), new InjectionConstructor(new InjectionParameter(typeof(CarViewModel), CarViewModelInstance)));
或者您可以在 MainWindow 构造函数上使用 [InjectionConstructor] 属性:
[InjectionConstructor]
public CarView(CarViewModel carViewModel) : this()
此外,您可以在构造函数参数上传递 [Dependency] 属性,这样 Unity 将尝试从其注册的实例中解析该参数的值:
[InjectionConstructor]
public CarView([Dependency] CarViewModel carViewModel) : this()
您的示例的最佳方法可能看起来像这样:
container.RegisterType<ICarViewModel, CarViewModel>("Car");
....
[InjectionConstructor]
public CarView([Dependency("Car")] CarViewModel carViewModel) : this()
有很多方法可以完成您需要做的事情。更多信息:https://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx
一些测试代码:
var container1 = new UnityContainer();
container1.RegisterType(typeof(IBar), typeof(Bar), "Bar");
container1.RegisterType<Foo>();
public interface IBar
{
}
public class Bar : IBar
{
}
public class Foo
{
public IBar Bar
{
get;
private set;
}
public Foo()
{
}
[InjectionConstructor]
public Foo([Dependency("Bar")] Bar bar)
{
Bar = bar;
}
}
您好,我在 WPF 应用程序中遇到依赖注入问题。这是我的代码: App.xaml.cs:
IUnityContainer container = new UnityContainer();
container.RegisterType<ICarViewModel, CarViewModel>();
container.RegisterType<MainWindow>();
MainWindow mainWindow = container.Resolve<MainWindow>();
mainWindow.Show();
CarViewModel.cs:
public ObservableCollection<Car> Cars{ get; } = new ObservableCollection<Car>()
{
new Car() {Name = "Audi"},
new Car() {Name = "Peugeot"},
new Car() {Name = "Renault"},
};
CarView.cs:
public partial class CarView : UserControl, ICarView
{
public CarView()
{
InitializeComponent();
}
public CarView(CarViewModel carViewModel) : this()
{
DataContext = carViewModel;
}
}
CarView.xaml:
<ItemsControl ItemsSource = "{Binding Path = Cars}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBlock Text = "{Binding Path = Name, Mode = OneWay}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
MainWindow.xaml:
<view:CarView x:Name = "CarViewControl"></view:CarView>
Unity 容器仍然只从 CarView 调用没有参数的构造函数。 谢谢指教
您可以这样注册类型:
container.RegisterType(typeof(MainWindow), typeof(MainWindow), new InjectionConstructor(new InjectionParameter(typeof(CarViewModel), CarViewModelInstance)));
或者您可以在 MainWindow 构造函数上使用 [InjectionConstructor] 属性:
[InjectionConstructor]
public CarView(CarViewModel carViewModel) : this()
此外,您可以在构造函数参数上传递 [Dependency] 属性,这样 Unity 将尝试从其注册的实例中解析该参数的值:
[InjectionConstructor]
public CarView([Dependency] CarViewModel carViewModel) : this()
您的示例的最佳方法可能看起来像这样:
container.RegisterType<ICarViewModel, CarViewModel>("Car");
....
[InjectionConstructor]
public CarView([Dependency("Car")] CarViewModel carViewModel) : this()
有很多方法可以完成您需要做的事情。更多信息:https://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx
一些测试代码:
var container1 = new UnityContainer();
container1.RegisterType(typeof(IBar), typeof(Bar), "Bar");
container1.RegisterType<Foo>();
public interface IBar
{
}
public class Bar : IBar
{
}
public class Foo
{
public IBar Bar
{
get;
private set;
}
public Foo()
{
}
[InjectionConstructor]
public Foo([Dependency("Bar")] Bar bar)
{
Bar = bar;
}
}