首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将IOC容器重新安装到Brownfield企业.net应用程序

将IOC容器重新安装到Brownfield企业.net应用程序
EN

Stack Overflow用户
提问于 2014-10-30 14:50:48
回答 1查看 163关注 0票数 3

我们有一个非常大的、复杂的企业应用程序,于2005年开始使用,当时IOC容器在.NET中还没有普及,我们希望对IOC容器进行改造,作为我们迁移到基于RabbitMQ (和easynetq)的完整事件驱动体系结构的一部分。作为一项业务,我们同意这将使我们的商业优势比我们的竞争对手。

我认为重要的是给出一些序言,因为执行战略是关键:

  • 1.5使用million+ 4的C#行,在600+项目、30000+类、部署在50多个不同应用程序端点(命令行exe、30000+服务、web服务等)中的40000+单元测试。
  • 应用程序的简单CRUD数量少于10%。大多数应用程序是复杂的事务处理,其中单个输入值可以轻松地通过20到30个依赖项,这些依赖项可能与2或3个其他子系统和/或模块通信。
  • 我们每月向所有不同配置的客户发布一次重要的新版本,应用程序非常稳定,但我们仍在积极创新。我们需要在12至36个月内迁移。
  • 可伸缩性和性能对我们非常重要。我们已经测试了超过1500个事务每秒和80 We的响应时间。每毫秒都很重要。
  • 非常稳定和相当一致的架构,在一个受控的庄园中不断发展-开发是相当没有痛苦的。

目前,所有依赖项注入都是基于构造函数并手工滚动的:

代码语言:javascript
复制
public sealed class TestCommandHandler
{
        private readonly IUnitOfWork _unitOfWork;
        private readonly ITestCommandValidator _testCommandValidator;

        public TestCommandHandler(IUnitOfWork unitOfWork)
        {
            this._unitOfWork = unitOfWork;
            this._testCommandValidator = new ITestCommandValidator(unitOfWork);
        }

        public TestCommandHandler(IUnitOfWork unitOfWork, IValidator testCommandValidator)
        {
            this._unitOfWork = unitOfWork;
            this._testCommandValidator = testCommandValidator;
        }
    }

工作单元包含对存储库的访问,这些存储库可以很容易地被模拟:

代码语言:javascript
复制
public class UnitOfWork : IUnitOfWork, IDisposable
{
        private IAccountRepository _accountRepository;

        public IAccountRepository Account
        {
            get
            {
                if(this._accountRepository == null)
                {
                    this._accountRepository = new AccountRepository(this);
                }
                return this._accountRepository;
            }
            set
            {
                this._accountRepository = value;
            }
        }
        //Begin Tx, Commit Tx etc
}

目前,所有的测试依赖项都是在调试模式下有条件编译的。发布代码使用非条件代码,我们在其中创建具体的依赖项。最大的对象依赖是UnitOfWork,它通常围绕每个业务事务创建并传递到堆栈中。例如,

代码语言:javascript
复制
using(var unitOfWork = new UnitOfWork())
{
}

这通常被包装在另一个也支持IDisposable的类中。我们还计划将AccountID传递到UnitOfWork中,这样我们就可以使用mod函数轻松地对不同的数据库进行分解。

为了转移到依赖框架,我们感觉需要首先对UnitOfWork进行排序,但是我们需要一个初步的步骤。我真的是在寻求关于用这么大的应用程序来实现这一目标的最佳方法的建议。我们计划在圣诞节期间做第一阶段,在那里我们有一个很好的冻结和合并在所有绝望的分支到一个主线分支来进行重大的改变。

我们打开了要使用的依赖注入框架。我们和StructureMap玩过了。我们看到Ninject在Nuget上有很高的下载统计数据,但是阅读它的性能得分很差。我们真的不希望有进一步的迁移过程到另一个依赖注入框架。因此,我们愿意听取建议。这不是一场最好的宗教战争,更重要的是我们有一些东西要迁移到。最重要的要求是它被流畅地配置以避免配置地狱。

我们关注的其他问题是StructureMap术语,即我们如何声明注册中心。我们是否为每个程序集声明注册表?大应用程序中文件夹、类名周围推荐的命名标准吗?我的粗略猜测是,将有大约1000个注册表。另外,对于这样大的代码库扫描策略有什么想法吗?我们应该关心吗?

谢谢你已经准备好了,但是背景很重要,因为这不是10分钟的工作。

休伯特

EN

回答 1

Stack Overflow用户

发布于 2014-10-30 16:14:36

张贴这作为一个答案,但没有正确的你的问题,只是为了克服评论的限制。

为了实现IoC,您在场景中有很多优点:

  1. 您的类已经解耦并为构造函数注入做好了准备;
  2. 使用条件标志拆分依赖项。

因此,我将根据你目前的情况,指出几点建议。

  • 如果性能是关键的,如果使用Ninject,请小心。作为一个大用户,我发现它非常灵活和强大,它的流畅配置,模块和上下文绑定。但是,所有这些功能都是有代价的,与其他IoC容器相比,每次激活请求的性能都要差得多。
  • 无论选择哪种框架,并且由于您开始引入这些更改,您都不希望被绑定到容器上。确保你抽象化它,然后你可以切换到另一个动态。
  • 您已经按照配置划分了“模块”。当插入容器配置代码时,请确保将它们收集到模块中。不要将所有模块配置在一个地方的所有依赖项都留在一个地方。Ninject支持模块,但是通过任何容器都可以很容易地实现这一点,特别是如果您抽象它们的话。不要为虚拟/真实实现使用相同的模块名称,而是根据配置加载一个模块或另一个模块。
  • 根据“自动注册”或“约定”,您应该是非常严格的,并且对标准非常小心,否则很容易搞砸。我强烈建议不要使用预先累进的自动注册查询,并将它们保持在"IAccountRepository“、”->“、"AccountRepository”或"AccountRepositoryImpl“等最小和非常简单的情况下。即使如此,您也可以将约定按模块拆分,以便为测试目的覆盖它们。
  • 在发布周期内通常做一些小的更改,不要做分支更改,直到集成它们为止。就像你说的,小步子。您已经有依赖注入,因此这将是无痛的。在团队中加强此策略,以使用容器,并在特性实现或重新工作时进行小的更改。

那是我的两分钱,希望能帮上忙。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26656182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档