【发布时间】:2014-10-30 14:50:48
【问题描述】:
我们有一个非常庞大、复杂的企业应用程序,它始于 2005 年,当时 IOC 容器还没有在 .NET 中广泛使用。我们希望改造一个 IOC 容器,作为我们迁移到基于 RabbitMQ(和 easynetq)的完整事件驱动架构的一部分。作为一家企业,我们同意这将使我们比竞争对手更具商业优势。
我觉得做一些序言很重要,因为实施策略是关键:
- 150 万多行 C# 使用 .net 4,在 600 多个项目、30000 多个类、40000 多个单元测试中部署在 50 多个不同的应用程序端点(命令行 exe、Windows 服务、Web 服务等)中。李>
- 应用程序具有的简单 CRUD 数量不到 10%。大多数应用程序都是复杂的事务处理,其中单个输入值可以轻松地通过 20 到 30 个依赖项,这些依赖项可能与 2 或 3 个其他子系统和/或模块通信。
- 我们每月向所有具有各种不同配置的客户发布一个重要的新版本,该应用程序非常稳定,但我们仍在积极创新。我们需要迁移 12 到 36 个月。
- 可扩展性和性能对我们来说非常重要。我们已经对每秒超过 1500 个事务和 80 毫秒的响应时间进行了负载测试。每一毫秒都很重要。
- 非常稳定且相当一致的架构,在受控庄园中不断发展 - 开发相当轻松。
目前所有的依赖注入都是基于构造函数的并且是手动的:
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;
}
}
工作单元包含对可以轻松模拟的存储库的访问:
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,它通常围绕每个业务事务创建并向下传递。例如,
using(var unitOfWork = new UnitOfWork())
{
}
这通常包装在另一个也支持 IDisposable 的类中。我们还计划将 AccountID 传递到 UnitOfWork 中,这样我们就可以使用 mod 函数轻松地对不同的数据库进行分片。
为了转移到依赖框架,感觉就像我们需要首先对 UnitOfWork 进行排序,但我们需要一个小步骤。我真的在寻找关于使用如此大的应用程序实现这一目标的最佳方法的建议。我们计划在圣诞节期间进行第一阶段,在此期间我们会很好地冻结并将所有绝望的分支合并到一个主线分支中以进行重大更改。
我们对使用哪个依赖注入框架持开放态度。我们对 StructureMap 进行了一些尝试。我们看到 Ninject 在 Nuget 上的下载统计数据很高,但读取它的性能得分很低。我们真的不希望进一步迁移到另一个依赖注入框架。所以我们愿意接受建议。这不是一场最好的宗教战争,更重要的是我们有一些东西可以迁移。最重要的要求是流畅地配置以避免配置地狱。
我们在 StructureMap 术语中的其他顾虑是我们如何声明注册表。我们是否声明每个程序集的注册表?在大型应用程序中,有什么推荐的围绕文件夹、类名的命名标准吗?我的粗略猜测是将有大约 1000 个注册表。另外,对于如此庞大的代码库的扫描策略有什么想法吗?我们应该担心吗?
感谢您到目前为止的准备,但背景很重要,因为这不是 10 分钟的工作。
休伯特
【问题讨论】:
-
我也使用了 ninject 很长一段时间,并且喜欢它的界面。由于您需要性能,因此我会研究 Autofac。它在功能方面类似于 Ninject,但似乎表现更好。另见:palmmedia.de/blog/2011/8/30/…
标签: .net dependency-injection ninject inversion-of-control structuremap