为什么我需要 IoC 容器而不是简单的 DI 代码? [关闭]

2023-11-29

我一直在使用依赖注入(DI) 一段时间,注入构造函数、属性或方法。我从来没有觉得有必要使用控制反转(国际奥委会)容器。然而,我读得越多,就越感受到来自社区的使用 IoC 容器的压力。

我玩过 .NET 容器,比如结构图, NInject, Unity, and Funq。我仍然不明白 IoC 容器将如何使我的代码受益/改进。

我也害怕在工作中开始使用容器,因为我的许多同事会看到他们不理解的代码。他们中的许多人可能不愿意学习新技术。

请让我相信我需要使用 IoC 容器。当我在工作中与开发人员同事交谈时,我将使用这些论点。


哇,不敢相信乔尔会喜欢这个:

var svc = new ShippingService(new ProductLocator(), 
   new PricingService(), new InventoryService(), 
   new TrackingRepository(new ConfigProvider()), 
   new Logger(new EmailLogger(new ConfigProvider())));

在此:

var svc = IoC.Resolve<IShippingService>();

许多人没有意识到您的依赖关系链可以嵌套,并且手动连接它们很快就会变得笨拙。即使有了工厂,重复代码也是不值得的。

是的,IoC 容器可能很复杂。但对于这个简单的例子,我已经证明它非常简单。


好吧,让我们进一步证明这一点。假设您有一些想要绑定到智能 UI 的实体或模型对象。这个智能 UI(我们称之为 Shindows Morms)希望您实现 INotifyPropertyChanged,以便它可以进行更改跟踪并相应地更新 UI。

“好吧,这听起来并不难”,所以你开始写作。

你从这个开始:

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime CustomerSince { get; set; }
    public string Status { get; set; }
}

..最终得到this:

public class UglyCustomer : INotifyPropertyChanged
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            string oldValue = _firstName;
            _firstName = value;
            if(oldValue != value)
                OnPropertyChanged("FirstName");
        }
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            string oldValue = _lastName;
            _lastName = value;
            if(oldValue != value)
                OnPropertyChanged("LastName");
        }
    }

    private DateTime _customerSince;
    public DateTime CustomerSince
    {
        get { return _customerSince; }
        set
        {
            DateTime oldValue = _customerSince;
            _customerSince = value;
            if(oldValue != value)
                OnPropertyChanged("CustomerSince");
        }
    }

    private string _status;
    public string Status
    {
        get { return _status; }
        set
        {
            string oldValue = _status;
            _status = value;
            if(oldValue != value)
                OnPropertyChanged("Status");
        }
    }

    protected virtual void OnPropertyChanged(string property)
    {
        var propertyChanged = PropertyChanged;

        if(propertyChanged != null)
            propertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

这是令人厌恶的管道代码,我坚持认为,如果你手动编写这样的代码你从你的客户那里偷东西。有更好、更智能的工作方式。

你听说过这个词吗?“更聪明地工作,而不是更努力地工作”?

想象一下,您团队中的某个聪明人走过来说:“这是一个更简单的方法”

如果您将您的财产设为虚拟(冷静下来,这没什么大不了的),那么我们可以weave自动在该属性行为中。 (这称为 AOP,但不用担心名称,专注于它将为您做什么)

根据您使用的 IoC 工具,您可以执行如下操作:

var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper());

Poof!现在,所有手动 INotifyPropertyChanged BS 都会在相关对象的每个虚拟属性设置器上自动生成。

这是魔法吗?YES!如果您可以相信此代码能够完成其工作,那么您可以安全地跳过所有属性包装的繁琐内容。您有业务问题需要解决。

IoC 工具执行 AOP 的其他一些有趣用途:

  • 声明式和嵌套数据库事务
  • 声明式和嵌套工作单元
  • Logging
  • 前置/后置条件(按合同设计)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我需要 IoC 容器而不是简单的 DI 代码? [关闭] 的相关文章

  • 如何使用标准 MVC Core 依赖注入解析未注册类型

    有没有办法得到IServiceProvider GetService
  • 解决IContainer

    从应用程序的类内部获取 Autofac 容器的建议方法是什么 Autofac 是否提供解析类上的 IContainer 属性 或者在构建容器后是否需要全局存储该容器 你需要IComponentContext or ILifetimeScop
  • 带有限定符的类型 Set 的依赖关系不满足

    我是创建 Web 服务 Restful api 的新手 遵循 Java Brains for Restful Web 服务的简单教程 我收到错误 内容类似于 带有限定符 Default 的类型集的依赖关系不满足 我在这里搜索了不同的问题 尝
  • Ninject 约定与 Ninject 工厂扩展将多种类型绑定到一个接口

    我正在尝试扩展标题为 SO 的问题中提出的场景Ninject Factory Extension 将多种具体类型绑定到一个接口 https stackoverflow com q 14451066 533958通过使用 Ninject Co
  • 使用 ASP.New MVC 4 Web Api 进行授权过滤器依赖注入

    我正在尝试在 MVC 4 Web Api 授权过滤器上实现依赖项注入 我创建了一个继承自 ActionDescriptorFilterProvider 的 FilterProvider public class UnityWebApiFil
  • 在 Jersey 中是否可以访问注入的 HttpServletRequest,而不是代理

    注射时HttpServletRequest在 Jersey JAX RS 资源中 注入的值是代理 例如 Path myResource class MyResource Inject HttpServletRequest request 会
  • 使用 @Assisted 注入与多个相同类型的参数(@Named params)

    我的问题归结为使用 Assisted 和工厂的两个字符串参数 问题是 因为 Guice 将类型视为参数的识别机制 所以两个参数是相同的 并且我收到配置错误 一些代码 public class FilePathSolicitingDialog
  • 当多个Spring Singleton实例同时访问时

    如果您在 Spring 配置中的单例范围内定义服务 那么如果多个用户尝试同时访问它 即作为依赖项注入到您的控制器中 会发生什么情况 它应该引起任何冲突吗 或者 IoC 容器将保留后面的调用直到第一个调用完成 如果是这样 它会降低大型应用程序
  • 如何使用@Configuration排除spring配置文件对其他项目的依赖

    我有一个项目 A In Maven 它依赖于项目 B In Maven 现在项目 B 得到了一些 spring Configuration db 配置 文件 这些文件在我构建和部署项目 A 时启动 但由于我的项目 A 中没有一些配置属性 它
  • 工厂中的依赖注入

    我对 DI 很陌生 但我真的很想尝试使用它 有件事我不明白 这是一个简单的工厂伪代码 我经常使用 class PageFactory public function construct dependency list save refere
  • 使用选项模式的依赖注入

    我正在尝试从 appsettings 文件加载一些设置 但在使用选项模式时加载列表的方式遇到了一个小问题 假设我有以下类 用于加载设置 public class Application public string Name get set
  • Dagger 2:何时使用构造函数注入,何时使用字段注入?

    我有点懒 过去几乎完全使用现场注入 我只是提供空的构造函数 放入我的 Inject 字段 我的一切看起来都很好很简单 然而 字段注入有其权衡 因此我设计了一些简单的规则来帮助我决定何时使用字段以及何时使用构造函数注入 如果我的逻辑有错误或者
  • 依赖注入陷阱

    有人在 www 上有一个链接列表来获取 DI 陷阱的好列表吗 我一直在尝试在 asp net webforms 应用程序中使用 DI 注入控件 发现在递归构建时 ViewState 会丢失 开发人员在应用程序中实施 IoC DI 之前需要注
  • ASP.NET MVC 5 中的 Actionfilter 注入

    我有一个简单的过滤器 public class IsAdmin ActionFilterAttribute IAuthenticationFilter private string roleName IBusinessIdentity id
  • 服务中有很多依赖项

    我在服务层的应用程序中遇到依赖关系问题 我有以下课程
  • Smalltalk 和 IoC

    我看到很多 Net 和 Java 的 IoC 框架 有谁知道为什么 Smalltalk 没有等效的框架 这更像是一个哲学问题 我想知道 Smalltalk 的做事方式中是否有某些东西排除了 IoC 框架的必要性 MVC http en wi
  • 枚举由 Autofac 生命周期跟踪的一次性物品

    Autofac 使用生命周期范围作为处理工作单元期间创建的所有组件的一种方式 虽然这是一个强大的功能 但很容易编写不能正确处理生命周期范围的代码 这会导致跟踪的一次性数量随着时间的推移而增长 实际上是内存泄漏 有没有办法监控生命周期范围在任
  • 将 Mockito 模拟注入 Spring bean

    我想将 Mockito 模拟对象注入到 Spring 3 bean 中 以便使用 JUnit 进行单元测试 我的 bean 依赖项当前是通过使用注入的 Autowired私有成员字段上的注释 我考虑过使用ReflectionTestUtil
  • 在 Fragment 和 Activity 之外通过 Hilt 进行现场注入

    我想知道是否可以在片段或活动之外使用字段注入 我知道我可以使用构造函数注入 但是我想知道是否也可以使用字段注入 我认为 Dagger 是可能的 当我尝试用注入的东西做某事时yclass字段我收到此错误 lateinit property y
  • PHP - 多个不同的数据库依赖注入类

    我花了过去几个小时试图找到 最佳 最合乎逻辑的方法的答案 以编写一个 php 数据库类以同时连接到一个 postgresql 数据库和一个 mysql 数据库 另外 我想采用依赖注入设计 但对整个概念还是陌生的 到目前为止我已经想出了 cl

随机推荐

  • 如何使用 Java prefuse 库创建条形图?

    我目前有prefuse绘制散点图 其中 X 轴是计算机名称 Y 轴是其温度 如何让它绘制显示值而不是离散点的条形 我目前正在使用以下代码来呈现点 ShapeAction shape new ShapeAction group Constan
  • 如何过滤大于x的数组值

    我一直在互联网上查找 但找不到任何介绍如何解决此问题的帖子 尽管我确信这是一个非常简单的修复 基本上我有一个包含数字值的数组 我想过滤掉任何大于 10 的数字并将它们添加到另一个数组中 这是到目前为止我所得到的 但我得到的是第一个数组中的所
  • 如何从 QUnit 测试触发本机 Javascript 事件?

    我正在开发一个不依赖于 jQuery 的 Javascript 库 尽管我的测试中可以使用 jQuery 和 QUnit 在库中 我按照 jQuery 的方式将事件附加到元素 if document addEventListener tab
  • 如何使用水豚has_text

    所以现在我已经让黄瓜 水豚 硒点击谷歌应用程序脚本 这很棒 但由于某种原因 我似乎无法按照我期望的方式检查页面正文中的文本 在调试器中 我可以抓取页面对象 我可以在浏览器中获得预期的文本 直接扫描html显示文本出现了两次 但是page h
  • 如何通过调整缓冲区大小来优化读写?

    如何优化标准 C C 11 中 std ifstream 和 std ofstream 的读写速度 无 POSIX 函数 1 我不太清楚缓冲区的作用 所以你能确认一下吗 用于读取 文件的很大一部分被预加载到内存中 因此缓冲区大小定义了这大部
  • Haskell:let 语句,将数据类型复制到自身(带/不带修改)不起作用

    我想通过更改一个字段来更新记录语法 所以我做了类似的事情 let rec rec field 1 但我发现我无法打印rec不再 意味着当我尝试时编译器似乎进入无限循环 所以我尝试这样做 let a 1 prints OK let a a n
  • UITextView - 禁用垂直滚动

    如何禁用 UITextView 中的垂直滚动 我希望它基本上只是水平滚动 在某些情况下 当试图限制不需要的 UITextView 滚动时 我发现向 UITextView 委托添加类似以下内容很有帮助 这是一个 UIScrollView 委托
  • 在 Powershell 中更新 VSTS WorkItem 的正确 Invoke-RestMethod 语法是什么 - 构造包含 Windows 路径的 JSON 字符串 [重复]

    这个问题在这里已经有答案了 当尝试使用 Invoke RestMethod 更新现有 VSTS 工作项时 我不断收到 您必须在请求正文中传递有效的补丁文档 这是我要传递的内容 Body op test path rev value 1 op
  • 使用 PHP 读取 MIME 数据

    我有一个第三方程序 它基本上允许用户发送电子邮件 然后将其显示在系统中 但问题是它生成这样的输出 我只想获取这些数据并将其格式化为合适的格式 我想避免正则表达式 是否有任何选项或标准方法可以以更美观的方式显示以下内容 基本上我会将下面的所有
  • 细胞景观。从 URL 加载依赖项

    这是一个非常简单的问题 如何通过 url 将 cytoscape 指示为来源 我知道与D3这很简单 cytoscape 的等效地址是什么 Thanks 您要查找的术语是 CDN 托管的代码副本 严格来说 即使您指定了本地副本 您仍然在使用
  • 在android中制作一个超链接textview

    我想为文本视图文本创建一个链接 例如Google 有没有办法建立这样的链接 即 当点击 Google 一词时 它应该打开相应的链接 欢迎任何想法 试试这个 让我知道会发生什么 使用java代码 TextView textView TextV
  • 使用nodejs从文件中删除最后n行

    我正在尝试使用 fs 作为 nodejs 的一部分从文件中删除最后 3 行 我目前正在将文件读入内存 然后在没有这 3 行的情况下再次写入它 但我确信有一种更有效的方法 不需要将整个文件读入内存 我现在的代码 fs readFile fil
  • 如何在 on_member_join()discord.py 中向成员发送私人消息?

    这就是我所拥有的 client command pass context True client event async def on member join ctx member print f member has joined a s
  • 如何在不使用 SMIL 的情况下制作路径形状动画?

    下面的代码片段显示了我想做的事情 但也存在一些问题 不使用SMIL如何制作这个动画 SMIL 已被弃用 并且浏览器支持较差 如何使黑色路径穿过蓝色路径的右端 红色 蓝色和绿色路径的长度相同 动画应该重复向下 向上 向下 向上 依此类推 第一
  • Fluent nHibernate:需要多对多自引用映射的帮助

    我有一个名为 User 的实体 它可以有一个名为 Friends 的其他用户列表 有点像 Facebook 在我的 User 实体中 我声明了一个公共虚拟 IList Friends get private set 属性 并在构造函数中创建
  • 使用 ng-options 时如何将所选选项的文本分配给另一个模型?

    我可以创建一个选择标签并将数据放入其中 我可以将该选择的选定选项分配给模型 但无法将其文本分配给另一个模型 这是下面的例子jsFiddle链接 html div div div div
  • 在 VS 2010 Express 版本中发布构建事件?

    到目前为止 我一直在 VS 2008 中使用后期构建事件 并下载了 2010 Express 版本来查看新功能 2008 年 构建事件位于项目属性 gt 编译 gt 构建事件中 我在 2010 Express 版本中没有看到该按钮 这是因为
  • pandas 到 csv TypeError: get_handle() 有一个意外的关键字参数“错误”

    我有一张大桌子 我根据日期将其切成许多小桌子 dfs for fecha in fechas dfs fecha df df date fecha set index Hour now I can acess the tables like
  • 如何从 moment.js 获取月份的整数值

    我正在使用 Moment js 将日期添加到我正在制作的选项列表中 以便我可以使用这些日期来显示可用的约会 例如 某人可以从选项列表中选择 2 月 3 日星期五 然后选择可用时间列表将于2月3日出现 我遇到的问题是我正在使用一个在线调度 A
  • 为什么我需要 IoC 容器而不是简单的 DI 代码? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 Locked 这个问题及其答案是locked因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 我一直在使用依赖注入 DI 一段时间 注入构造函数 属性或方法 我从来没有觉得