【问题标题】:IoC Container doesn't work on WebFormsIoC 容器不适用于 WebForms
【发布时间】:2016-07-09 08:41:24
【问题描述】:

我想使用 ASP.NET Web 表单实现 IoC 容器。我已完成以下步骤:

  1. 安装NinjectNinject.Webddl

  2. public class Global : NinjectHttpApplication

  3. 创建Kernel

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

    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();
        }
    }
    

这是我的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");
        }
 }

据我了解,当在MetricService 构造函数中传递IMetricService 时,IoC 容器必须绑定此MetricService 类。我认为我的错误是一般性的,但我不明白在哪里。

【问题讨论】:

  • DI 的想法是让你没有依赖项,在你的 PageInit 中你正在新建一个依赖项?
  • PageInit 我需要做什么?
  • 先去掉metricService = new MetricService(metricService);容器将为您提供正确的实例。
  • 我不明白你的意思
  • 这让我相信您并不完全了解 DI 容器的用途。 DI 容器将抽象映射到具体化,因此在您的类中,您不必依赖具体化,从而减少耦合。当您执行“新”操作时,您正在创建一个实例,因此完全否定了容器为您所做的工作。看看这个也许并阅读更多关于 DI 的内容。 stackoverflow.com/questions/4933695/…

标签: c# asp.net webforms inversion-of-control ioc-container


【解决方案1】:

您需要使用带有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 更改为您要返回的类型。

【讨论】:

    【解决方案2】:

    我可以这样做吗?

            [Inject]
            private IMetrics metrics;
    
            protected void Page_Init(object sender, EventArgs e)
            {
                metrics = new Metrics(metrics);
            }
    

    我在哪里

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

    这是我的度量类

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

    当我将指标放入 Page_Init Ninject Container 时,放入真正的 Metric 类,或者我需要用户属性来执行此操作。我的想法是在 PageMetric 将此 IMetri* 接口归类为具有有效状态


    当我以这种方式进行时抛出异常

            [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.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多