【问题标题】:Need to pass class object to ninject需要将类对象传递给ninject
【发布时间】:2023-03-04 09:02:01
【问题描述】:

所以我正在研究 API 并将 Ninject 用于 DI 和 IoC。我知道基本代码是如何使用 Ninject 工作的,但是在其中一个类的构造函数中,正在发送 Logger 的对象。我不想在构造函数设计项中发送它,而是在NinjectWebCommon.cs 文件中传递它。

public GAMonthlyAPIController() : this(new GAMonthlySQLReader(new NullLogger())) 

这是构造函数。

kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();

这是NinjectWebCommon.cs 中的条目我想将它绑定到NinjectWebCommon.cs 而不是默认值。我怎么能通过呢?我什至不知道要搜索什么,所以我可以找到答案。

【问题讨论】:

    标签: c# dependency-injection inversion-of-control ninject ninject.web.mvc


    【解决方案1】:

    应用依赖注入模式最实用的方法是使用构造函数注入。这意味着GaMonthlyAPIController 所依赖的类应该通过构造函数传入,而不是在控制器内部硬编码。

    public class GAMonthlyAPIController
    {
        private readonly IGAMonthlySQLReader gaMonthlySqlReader;
    
        public GAMonthlyAPIController(IGAMonthlySQLReader gaMonthlySqlReader)
        {
            this.gaMonthlySqlReader = gaMontlySqlReader 
                ?? throw new ArgumentNullException(nameof(gaMontlySqlReader));
        }
    
        // implementation of controller...
    }
    

    这应该是控制器类的唯一构造函数。控制器本身对GAMontlySqlReader 或其任何依赖项一无所知。

    GAMonthlySQLReader 也是如此 - 它将允许通过构造函数注入任何 ILogger 实现。

    这个想法是它让应用程序的composition root 负责如何将依赖项组合在一起,这意味着您以后可以轻松地切换它们,而无需对正在组合的组件进行任何更改。因此,Ninject 将在您的组合根内部使用以将类型映射到它们的抽象,然后将构建所有组合在一起的依赖项的对象图

    kernel.Bind<ILogger>().To<MyLoggerClass>();
    kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
    

    对于每个应用程序服务,您将允许 Ninject 实例化它们(以便它可以提供依赖项),而不是在应用程序内部使用 new 关键字(new 可用于 DTO 和模型,不过)。

    【讨论】:

    • 所以我使用的记录器用于实例化 GAMonthlySQLReader 类。该类中使用了 Logger(现在什么都不做,只会记录它必须做的任何事情)。这就是我想传递它的原因。如果我声明以下行 kernel.Bind().To();我不必将它传递给公共 GAMonthlyAPIController(IGAMonthlySQLReader gaMonthlySqlReader) 而是在类中实例化?希望这是有道理的
    • 如果你像dave's answer那样向MVC注册Ninject,你的控制器将通过Ninject实例化。当控制器被实例化时,Ninject 将处理实例化和传递所有依赖项(前提是它们使用Bind 或类似方法向 Ninject 注册)。它将解析控制器的整个对象图。稍后,如果您决定要使用不同的记录器,您只需更改 Ninject 配置,它将为整个应用程序切换。
    【解决方案2】:

    我认为您需要使用 nuget 将 Ninject.Web.WebApi 添加到您的 Web Api 项目中。然后使用 Ninject 创建 ApiControllers:

    GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
    

    并为 GAMonthlyAPIController 添加 Bind()。无需为您的控制器创建默认构造函数。

    看看这篇文章: http://nodogmablog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/

    【讨论】:

    • 你的链接肯定有帮助,因为我看到了一个没有找到默认构造函数的异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 2012-01-17
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多