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;
      }
 }