2016-08-04 2 views
0

Привет, у меня возникла проблема с инъекцией зависимостей в приложении WPF. Вот мой код: App.xaml.cs:WPF Зависимость впрыска

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. Спасибо за советы

+0

Вынуть конструктор без параметров? Вероятно, это просто не подходит для использования этого. – Clint

+0

Что? Пожалуйста, покажите мне, как это сделать? – bluray

+0

Вы просто удаляете конструктор, который не принимает никаких параметров, и сохраняйте тот, который делает. Обязательно переместите вызов на InitializeComponent() 'на конструктор, который принимает параметры и удаляет вызов': this() ', и вы должны быть в порядке. – Clint

ответ

2

Вы можете зарегистрировать тип таким образом:

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

Или вы можете использовать [InjectionConstructor] атрибут MainWindow конструктор:

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

Кроме того, вы можете передать [Завис ] в параметре конструктора, поэтому 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; 
     } 
} 
+0

Спасибо, я использую последний пример, но все же вызываю первый конструктор (без параметра). – bluray

+0

Странно. Атрибут [InjectionConstructor] сообщает Unity, что это один конструктор, который нужно назвать. Я посмотрю. – paYa

+0

Вы уверены, что второй конструктор не называется вообще? Я сделал несколько тестов, и код правильный. Обратите внимание: ваш первый конструктор (без параметра) также будет вызван (из-за «: this()» во втором конструкторе). – paYa

Смежные вопросы