使用StructureMap将构造函数的ModelState传递给它的Service

时间:2010-02-27 17:49:01

标签: asp.net-mvc dependency-injection structuremap

我有这个控制器

public class AdminController : Controller
{
 private IAdministratorService _administratorService;

 public AdminController(IAdministratorService administratorService)
 {
  _administratorService = administratorService;
 }
}

我就是这样:

 private ModelStateDictionary _modelState;

 public AdministratorService(IRepository repository, ModelStateDictionary modelState)
 {
  _repository = repository;
  _modelState = modelState;
 }

我为控制器配置了依赖注入,因此除了从Container发送ModelState之外,它将正确加载。你是怎么做到的?

2 个答案:

答案 0 :(得分:0)

你应该真的避免这样的循环引用。您的服务类不应该依赖于控制器或System.Web.Mvc程序集中的任何内容。根据服务层中发生的事件,控制器或某个动作过滤器或模型绑定器的角色是操纵ModelState

答案 1 :(得分:0)

以下是解决此问题的一种方法......

...控制器

Public Class AdminController
  Inherits System.Web.Mvc.Controller

  Private _adminService as IAdminService

  Public Sub New(adminService as IAdminService)

    _adminService = adminService

    'Initialize the services that use validation...
    _adminService.Initialize(New ModelStateWrapper(Me.ModelState))

  End Sub

  ...

End Class

...服务

Public Class AdminService
  Implements IAdminService

  Private _repository As IAdminRepository
  Private _dictionary as IValidationDictionary

  Public Sub New(repository as IAdminRepository)

    _repository = repository

  End Sub

  Public Sub Initialize(dictionary As IValidationDictionary) Implements IAdminService.Initialize

    _dictionary = dictionary

  End Sub

  ...

End Class

包装器接口......

Public Interface IValidationDictionary

  ReadOnly Property IsValid() As Boolean
  Sub AddError(Key as String, errorMessage as String)

End Interface

包装器实施......

Public Class ModelStateWrapper
  Implements IValidationDictionary

  Private _modelState as ModelStateDictionary

  Public ReadOnly Property IsValid() As Boolean Implements IValidationDictionary.IsValid
    Get
      Return _modelState.IsValid
    End Get
  End Property

  Public Sub New(modelState as ModelStateDictionary)

    _modelState = modelState

  End Sub

  Public Sub AddError(key as string, errorMessage as string) Implements IValidationDictionary.AddError

    _modelState.AddModelError(key, errorMessage)

End Class

使用ModelStateWrapper可以使服务类与MVC松散耦合。虽然,由于New语句,我们确实在AdminController和ModelStateWrapper之间存在紧密耦合,但我并不在意,因为模型状态无论如何都是MVC特定的。通过这样做,您不需要使用StructureMap注册ModelStateWrapper或ModelState。

在单元测试中,您可以在创建控制器之后调用服务上的Initialize方法,以传递测试模型状态并检查验证错误。

我知道你曾说过你在使用ModelStateWrapper,但只是想添加一个更完整的例子来帮助别人...