Asp.net mvc 使用StructureMap将构造函数的ModelState传递给其服务

Asp.net mvc 使用StructureMap将构造函数的ModelState传递给其服务,asp.net-mvc,dependency-injection,structuremap,Asp.net Mvc,Dependency Injection,Structuremap,我有这个控制器 public class AdminController : Controller { private IAdministratorService _administratorService; public AdminController(IAdministratorService administratorService) { _administratorService = administratorService; } } 我有一个: private Mod

我有这个控制器

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;
 }

我已经为控制器配置了依赖项注入,因此除了从容器发送ModelState之外,它可以正常加载。你是怎么做到的?

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

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

这里是处理此问题的一种方法

控制器

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松散耦合。虽然,由于新语句,AdminController和ModelStateWrapper之间确实存在紧密耦合,但我并不在意,因为模型状态是特定于MVC的。这样,您就不需要向StructureMap注册ModelStateWrapper或ModelState

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


我知道您说过您正在使用ModelStateWrapper,但只是想添加一个更完整的示例来帮助其他人…

这里有一种处理此问题的方法

控制器

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松散耦合。虽然,由于新语句,AdminController和ModelStateWrapper之间确实存在紧密耦合,但我并不在意,因为模型状态是特定于MVC的。这样,您就不需要向StructureMap注册ModelStateWrapper或ModelState

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


我知道您说过要使用ModelStateWrapper,但只是想添加一个更完整的示例来帮助其他人…

事实上,我使用的是从字典继承的ModelStateWrapper。该服务使用IErrorDictionary,因此不绑定到System.Web.Mvc。我写这篇文章是为了简单,事实上我使用的是从字典继承的ModelStateWrapper。该服务使用IErrorDictionary,因此不绑定到System.Web.Mvc。我写这篇文章是为了简单你能澄清ModelState的来源吗?如果您没有使用容器,您将如何将ModelState实例传递给服务?您能否澄清ModelState来自何处?如果您没有使用容器,您将如何将ModelState实例传递给服务?甚至我也提出了这种方法来解决这个问题!然而,你明白了。。。即使这不是真正的解决方案,我也想出了这个方法来解决这个问题!然而,你明白了。。。尽管这并不是解决办法