Sento che mi manca qualcosa di ovvio. Ho letto diverse domande correlate qui e ho letto la pagina dei binding contestuali aggiornata sul wiki di Ninject ma purtroppo continua a non funzionare.Ninject binding with WhenInjectedInto metodo di estensione
Sto tentando di installare in un secondo momento un'applicazione legacy che utilizzava un pattern factory per utilizzare Ninject.
Ho 1 interfaccia (IInterface) implementata da 2 classi (ClassB e ClassC). IInterface ha un metodo di caricamento. Nel metodo di caricamento di ClassB crea un'istanza di ClassC e quindi esegue il suo metodo di caricamento.
Fondamentalmente il flusso del programma è ClasseA crea ClassB ed esegue il metodo di caricamento. Nel metodo di caricamento ClassB crea ClassC che funziona.
miei attacchi sono settati come così ...
Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>().WhenInjectedInto<ClassA>();
Quando questo viene eseguito non riesce a metodo load di ClassB con questo errore ...
errore che attiva IInterface Nessun attacchi di corrispondenza sono disponibili, e il il tipo non è autoindicabile.
Se provo quanto segue ...
Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>();
Fa un ciclo infinito e non crea mai ClassC.
EDIT ho semplificato questo in una prova di unità che passa, ma non mi dà i risultati che voglio ...
[TestClass]
public class NinjectTestFixture
{
private interface IDoSomething
{
void SaySomething();
}
private class ClassA : IDoSomething
{
public void SaySomething()
{
Console.WriteLine("Hello from Class A");
}
}
private class ClassB : IDoSomething
{
private IKernel _Kernel;
public ClassB(IKernel kernel)
{
_Kernel = kernel;
}
public void SaySomething()
{
Console.WriteLine("Hello from Class B");
var x = _Kernel.Get<IDoSomething>();
x.SaySomething();
}
}
private class ClassC
{
private IKernel _Kernel;
public ClassC(IKernel kernel)
{
_Kernel = kernel;
}
public void SaySomething()
{
Console.WriteLine("Hello from Class C");
var x = _Kernel.Get<IDoSomething>();
x.SaySomething();
}
}
[TestMethod]
public void TestMethod1()
{
var kernel = new StandardKernel();
kernel.Bind<IDoSomething>().To<ClassA>();
kernel.Bind<IDoSomething>().To<ClassB>().WhenInjectedInto<ClassC>();
kernel.Bind<ClassC>().ToSelf();
var x = kernel.Get<ClassC>();
x.SaySomething();
}
L'output è: Ciao da Classe C Ciao dalla classe A
Ma io voglio: Ciao dalla classe C Ciao dalla classe B Ciao dalla Classe A
Grazie
Capisco cosa stai dicendo, ma nel metodo SaySomething ho bisogno di istanziare un oggetto per fare un po 'di lavoro. Nella stessa classe ci sono altri metodi che istanziano i metodi per fare più lavoro. Se avessi fatto ciò che stai suggerendo avrei circa 20 parametri nel mio costruttore. Il codice è stato originariamente scritto oltre 6 anni fa, quindi sto provando ad aggiornarlo gradualmente con DI.Mi sono tormentato su come fare questo e passare il kernel era la soluzione più semplice che avesse più senso. Ho guardato il luogo del servizio e questo non aveva senso dato l'attuale base di codice. – oliwa
La tua risposta è corretta. Quando ho apportato le modifiche che hai proposto, ho ottenuto i risultati che mi aspettavo. – oliwa
Capisco cosa intendi: anche io ho rifatto i sistemi in cui ho dovuto usare alcuni passaggi intermedi dispari/orribili per introdurre DI. –