bluray
bluray

Reputation: 1953

WPF Dependency injection

Hello i have a problem with dependency injection in WPF application. Here is my code: 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 container still call only constructor without parameters from CarView. Thanks for advice

Upvotes: 0

Views: 967

Answers (1)

paYa
paYa

Reputation: 231

You can register the type this way:

 container.RegisterType(typeof(MainWindow), typeof(MainWindow), new InjectionConstructor(new InjectionParameter(typeof(CarViewModel), CarViewModelInstance)));

Or you can use [InjectionConstructor] attribute on MainWindow constructor:

 [InjectionConstructor]
 public CarView(CarViewModel carViewModel) : this()

Also, you can pass the [Dependency] attribute on constructor parameter, so Unity will try to resolve value for that parameter from its registered instances:

 [InjectionConstructor]
 public CarView([Dependency] CarViewModel carViewModel) : this()

The best approach for your example could maybe looks somehow like this:

 container.RegisterType<ICarViewModel, CarViewModel>("Car");
 ....
 [InjectionConstructor]
 public CarView([Dependency("Car")] CarViewModel carViewModel) : this()

There is a lot of ways to do what you need to do.. More info: https://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx

Some test code:

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

Upvotes: 1

Related Questions