2012-11-17 6 views
6

Ich bin verloren mit Ninject in WPF.WPF App mit Ninject

Ich initialisiere es in App.xaml, aber die ITest-Eigenschaft in MainWindow.xaml (auch mit dem InjectAttribute) wird nicht aufgelöst und bleibt null.

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    {  
     IKernel kernel = new StandardKernel(); 
     kernel.Bind<ITest, Test>(); 
     base.OnStartup(e); 
    } 
} 

Ich googelte ein bisschen und fand heraus, dass es so nicht funktioniert. Bei dem Versuch, eine Lösung zu finden, habe ich IMainWindow mit nichts anderem als "void Show()" erstellt. und es zum MainWindow hinzufügen.

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    {  
     IKernel kernel = new StandardKernel(); 
     kernel.Bind<ITest, Test>(); 

     kernel.Bind<IMainWindow, MySolution.MainWindow>(); 
     kernel.Get<IMainWindow>().Show(); 

     base.OnStartup(e); 
    } 
} 

Dafür bin ich

mit .Get eine Nullreferenceexception auf der Linie bekommen

Ich habe auch versucht dies:

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    {  
     IKernel kernel = new StandardKernel(); 
     kernel.Bind<ITest, Test>(); 

     MainWindow = new MySolution.MainWindow(kernel); 
     //then kernel.Inject(this); in the MainWindow constructor 
     MainWindow.Show(); 

     base.OnStartup(e); 
    } 
} 

Jetzt eine Nullreferenceexception an der Linie Ich bin .Inject bekommen im Hauptfenster.

Ich fand eine andere verschiedene Lösungen, aber sie schienen Schwergewicht und ich gab es auf, alle von ihnen zu testen und zu versuchen, welche funktioniert.

Irgendwelche Hilfe bitte?

+0

Was genau ist Ihr 'NullReferenceException' ist? – AgentFire

Antwort

5

Sie registrieren Ihre Typen nicht korrekt, weshalb das zweite Beispiel eine Ausnahme auslöst. Die korrekte Syntax ist: kernel.Bind<SomeInterface>().To<SomeImplementation>()

So die korrekte Nutzung:

protected override void OnStartup(StartupEventArgs e) 
{ 
    IKernel kernel = new StandardKernel(); 
    kernel.Bind<ITest>().To<Test>(); 

    kernel.Bind<IMainWindow>().To<MainWindow>(); 
    var mainWindow = kernel.Get<IMainWindow>(); 
    mainWindow.Show(); 

    base.OnStartup(e); 
} 

Und Sie benötigen eine Eigenschaft mit dem [Inject] Attribut markieren:

public partial class MainWindow : Window, IMainWindow 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    [Inject] 
    public ITest Test { get; set; } 
} 

public interface IMainWindow 
{ 
    void Show(); 
} 
+0

Huh, ich dachte Bind () ist das gleiche wie Bind (). Zu (). Offensichtlich nicht. Vielen Dank! – Mirek

+0

Nein mit 'Bind ()' können Sie zwei Schnittstellen an eine Implementierung binden, müssen aber die Implementierung mit '.To <>' versehen. – nemesv

+0

Ich weiß, das ist alt, aber wenn ich das tue, bekomme ich zwei Hauptfenster, im Gegensatz zu einem. Irgendwelche Gedanken? – JMK

0

Ich bin sicher, dass Sie eine Lösung erhalten, Sie können jedoch die Konstruktorinjektion anstelle von Property-Injection auf MainWindow verwenden, wenn Sie möchten.

Dies vermeidet das Erstellen einer Dummy-Schnittstelle IMainWindow und das Erstellen einer unnötigen öffentlichen Eigenschaft für alle Ihre injizierten Klassen.

Hier ist die Lösung:

MainWindow.cs

public partial class MainWindow : Window, IMainWindow 
{ 
    private readonly ITest test; 

    public MainWindow(ITest test) 
    { 
     this.test = test; 
     InitializeComponent(); 
    } 

} 

App.xaml.cs:

protected override void OnStartup(StartupEventArgs e) 
{ 
    IKernel kernel = new StandardKernel(); 
    kernel.Bind<ITest>().To<Test>(); 

    var mainWindow = kernel.Get<MainWindow>(); 
    mainWindow.Show(); 

    base.OnStartup(e); 
}