2016-03-22 7 views
2

Ich möchte IoC-Container mithilfe von ASP.NET-Webformularen implementieren.IoC-Container funktioniert nicht auf WebForms

  1. Ninject und Ninject.Web ddl

  2. public class Global : NinjectHttpApplication

  3. erstellen Kernel

    public override IKernel CreateKernel() 
    { 
        IKernel kernel = new StandardKernel(new Module.Module()); 
        return kernel; 
    } 
    
  4. erstellen Module

    installieren 012: Ich bin diese Schritte abgeschlossen
    public override void Load() 
    { 
        Bind<IMetricService>().To<MetricService>(); 
    } 
    
  5. Inject Verwendung auf Page

    public partial class _Default : Page 
    { 
        [Inject] 
        private IMetricService metricService; 
    
        protected void Page_Init(object sender,EventArgs e) 
        { 
         metricService = new MetricService(metricService); 
        } 
    
        protected void Page_Load(object sender, EventArgs e) 
        { 
         metricService.GetAllMetrics(); 
        } 
    } 
    

Und das ist meine MetricService Klasse

public class MetricService : IMetricService 
{ 
     [Inject] 
     private IMetricService _metricService; 

     public MetricService(IMetricService metricService) 
     { 
      this._metricService = metricService; 
     } 

     public void GetAllCriteria() 
     { 
      _metricService.GetAllCriteria(); 
      Console.WriteLine("metric service"); 
     } 
} 

Wie ich verstehe, wenn die IMetricService in MetricService Konstruktor der Container IoC passieren muss diese MetricService binden Klasse. Ich denke, mein Fehler ist allgemein, aber ich kann nicht verstehen, wo.

+0

Die Idee von DI ist, so dass Sie nicht haben, hängen von Konkrementen, in Ihrem Pageinit Sie sind newing up eine Abhängigkeit? – Magrangs

+0

In ** PageInit ** was muss ich tun? –

+0

Zuerst metricService = new MetricService (metricService) loswerden; Der Container liefert Ihnen die richtige Instanz. – Magrangs

Antwort

3

Sie müssen öffentliche Eigenschaften mit dem Attribut Inject verwenden, damit sie angezeigt werden können. Verlassen Sie sich auch nicht auf eine konkrete Implementierung der Klasse MetricService. Die Klasse, die den Dienst konsumiert, sollte sich nur auf eine abstrahierte Implementierung verlassen (die Schnittstelle, in diesem Fall IMetricService).

public partial class _Default : Page 
{ 
    [Inject] 
    public IMetricService metricService { get; set; } 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     metricService.GetAllMetrics(); 
    } 
} 

Und Metric Service braucht keine Instanz von sich. Das ist nur ein Rezept für eine Katastrophe. Ändern Sie Ihre MetricService-Klasse so, dass sie jetzt alle Kriterien abruft, ohne sich über Rekursion selbst aufrufen zu müssen.

public class MetricService : IMetricService 
{ 
    public void GetAllCriteria() 
    { 
     //this is where you call out to your database 
     //or do whatever else you need to do to return the criteria 
    } 
} 

Auch ich nehme es, dass GetAllCriteria soll etwas zurück? In der Regel bedeuten Methoden, die mit dem Präfix "get" beginnen. Daher müssen Sie den Rückgabetyp von void in den Typ ändern, den Sie zurückgeben.

0

Kann ich auf diesem Weg machen?

 [Inject] 
     private IMetrics metrics; 

     protected void Page_Init(object sender, EventArgs e) 
     { 
      metrics = new Metrics(metrics); 
     } 

Wo ich

private static void RegisterServices(IKernel kernel) 
     { 
      kernel.Bind<IMetrics>().To<Metrics>(); 
     }  

haben Dies ist meine Metric Klasse

public class Metrics : IMetrics 
    { 
     private IMetrics metrics; 

     public Metrics(IMetrics metrics) 
     { 
      this.metrics = metrics; 
     } 
    } 

Und wenn ich die Metrik in Page_Init setzen Ninject Container stellen die reale Metric Klasse oder ich brauche, um Benutzereigenschaft um das zu tun.Meine Idee ist in der Seite und in der Metric Klasse diese IMetri * interfa ce, um einen gültigen Zustand zu haben.


Wenn ich auf diese Weise Ausnahme machen geworfen

 [Inject] 
     public IMetrics metrics { get; set; } 

     protected void Page_Init(object sender, EventArgs e) 
     { 
      metrics = new Metrics(metrics); 
     } 

Error activating IMetrics using binding from IMetrics to Metrics 
A cyclical dependency was detected between the constructors of two services. 
Activation path: 
3) Injection of dependency IMetrics into parameter metrics of constructor of type Metrics 
2) Injection of dependency IMetrics into property metrics of type _Default 
1) Request for default_aspx 

Suggestions: 
1) Ensure that you have not declared a dependency for IMetrics on any implementations of the service. 
2) Consider combining the services into a single one to remove the cycle. 
3) Use property injection instead of constructor injection, and implement IInitializable 
    if you need initialization logic to be run after property values have been injected.