2016-03-22 5 views
2

ASP.NET Webフォームを使用してIoCコンテナを実装したいと考えています。私は、これらのステップを完了しています:WebフォームでIoCコンテナが動作しない

  1. Module

    012を作成Kernel

    public override IKernel CreateKernel() 
    { 
        IKernel kernel = new StandardKernel(new Module.Module()); 
        return kernel; 
    } 
    
  2. を作成NinjectNinject.Web DDL

  3. public class Global : NinjectHttpApplication

  4. をインストールします。ジェクトを使用して

    public override void Load() 
    { 
        Bind<IMetricService>().To<MetricService>(); 
    } 
    
  5. 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(); 
        } 
    } 
    

上のそして、これはIoCコンテナはこのMetricServiceをバインドする必要がありますMetricServiceコンストラクタでIMetricServiceを渡すときに私は理解したように私MetricServiceクラス

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

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

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

ですクラス。私のミスは一般的だと思うが、どこを理解するのか分からない。

+0

を投げられるこの方法で作ります依存関係? – Magrangs

+0

** PageInit **で何をする必要がありますか? –

+0

まず、metricService = new MetricService(metricService)を削除します。コンテナは正しいインスタンスを提供します。 – Magrangs

答えて

3

Inject属性を持つ公開プロパティを使用する必要があります。また、MetricServiceクラスの具体的な実装には依存しないでください。サービスを消費するクラスは抽象化された実装(この場合はIMetricServiceのインタフェース)にのみ依存する必要があります。

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

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

メトリックサービスは、それ自体のインスタンスを必要としません。それはただの災難のレシピです。 MetricServiceクラスを変更して、再帰を介して自分自身を呼び出す必要なしにすべての条件を取得できるようにします。

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

また、GetAllCriteriaは何かを返すと思われますか?これは通常、接頭辞「get」で始まるメソッドです。したがって、戻り値の型をvoidから戻り値の型に変更する必要があります。

0

このようにすることはできますか?

私はこれが私のメトリッククラス

public class Metrics : IMetrics 
    { 
     private IMetrics metrics; 

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

そして、私は本当のメトリッククラスを置くか、私は、ユーザーのプロパティに必要Page_Init Ninjectコンテナにメトリックを入れてある

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

を持って

 [Inject] 
     private IMetrics metrics; 

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

私のアイデアはこのIMetri * interfaのクラスのページメトリックです。 ceは有効な状態です。


私は例外があなたのPageInitにあなたがアップNEWINGあり、結石に依存していないようにDIの考え方がある

 [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. 
関連する問題