在MVC中使用DI时的大规模控制器构造函数参数列表

Seb*_*n K 4 c# dependency-injection autofac asp.net-mvc-3

我正在使用ASP.NET MVC3解决方案,该解决方案使用依赖注入与autofac.我们的控制器是由autofac正确创建的,所有必需的对象都被正确传入.这些对象通常包括将域对象转换为MVC(视图)模型的服务,存储库和映射器.所以控制器构造函数看起来有点像:

public abcController(
        ILogger logger,
        IabcRepository abcRepository,
        IabcService abcService,
        IMapper<AbcDomain, AbcViewModel> abcMapper,
        ...
        )
Run Code Online (Sandbox Code Playgroud)

不幸的是,随着时间的推移,这些构造函数参数列表往往会很快增长.我们的一些控制器现在需要60个或更多参数.

我们在这里创造了一些反模式吗?

编辑

我应该提到我们试图遵循薄的控制器模式.此外,大多数参数都是映射器 - 大约66%.控制方法通常非常简单,并遵循以下模式:

  • 基于参数调用适当的服务或存储库
  • 使用mapper将结果转换为适当的视图模型
  • 传递视图模型进行查看

或者这种模式:

  • 从后期行动中接收模型
  • 使用mapper将其转换为适当的域对象
  • 使用域对象调用适当的服务或存储库

Tra*_*lig 8

我真的不能说你应该如何重新构建你的控制器,虽然我同意大多数其他答案 - 60个传入的参数是很多.

可能有助于减少参数数量而不是依赖数量的东西是Autofac具有的Aggregate Service支持.

您可以采用一个包含60个属性的聚合参数,而不是直接获取60个参数.

您可以使用依赖项创建一个接口(只是接口,您实际上不必实现它):

public interface IMyAggregateService
{
  IFirstService FirstService { get; }
  ISecondService SecondService { get; }
  IThirdService ThirdService { get; }
  IFourthService FourthService { get; }
}
Run Code Online (Sandbox Code Playgroud)

然后修改您的控制器以获取该聚合接口:

public class SomeController
{
  private readonly IMyAggregateService _aggregateService;

  public SomeController(
    IMyAggregateService aggregateService)
  {
    _aggregateService = aggregateService;
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以注册聚合服务接口,依赖项和控制器,当您解析控制器时,将自动为您实施和解决聚合服务接口.

var builder = new ContainerBuilder();
builder.RegisterAggregateService<IMyAggregateService>();
builder.Register(/*...*/).As<IFirstService>();
builder.Register(/*...*/).As<ISecondService>();
builder.Register(/*...*/).As<IThirdService>();
builder.Register(/*...*/).As<IFourthService>();
builder.RegisterType<SomeController>();
var container = builder.Build();
Run Code Online (Sandbox Code Playgroud)

同样,它并没有涉及需要许多依赖项的更大问题,但如果您只是想简化构造函数和控制器上的属性数量以使其更易于管理,这是Autofac提供的一个策略. .

查看维基页面了解更多详情.


hea*_*150 6

60个或更多参数很多.

在您的问题中,您说"..这些对象通常包括将域对象转换为MVC(视图)模型的服务,存储库和映射器......"

你有一个胖控制器(不是托马斯任务引擎类),而是一个做得太多的控制器.

我寻找的平衡是Fat Model瘦的控制器.Ian Cooper在这篇博文中谈到了这一点

您还可以查看哪些参数实际上是交叉问题.

例如,我认为Mapping和Logging是跨领域的问题,因此您可以使用Action Filters来清理控制器.