2010-02-27 11 views
2

J'ai ce contrôleurPasser le ModelState d'un constructeur à son service en utilisant StructureMap

public class AdminController : Controller 
{ 
private IAdministratorService _administratorService; 

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

Et j'ai ceci:

private ModelStateDictionary _modelState; 

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

J'ai configuré injection de dépendance pour les contrôleurs de sorte qu'il chargerait correctement sauf pour envoyer le ModelState à partir du conteneur. Comment faites-vous?

+0

Pouvez-vous préciser où le ModelState vient? Si vous n'utilisiez pas de conteneur, comment transmettriez-vous l'instance ModelState au service? –

Répondre

0

Voici une façon de gérer ce problème ...

Controller ...

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 

service ...

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 

Wrapper Interface ...

Public Interface IValidationDictionary 

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

End Interface 

Implémentation de wrapper ... L'utilisation de ModelStateWrapper permet aux classes de service d'être faiblement couplées à MVC. Bien que, nous ayons un couplage serré entre l'AdminController et le ModelStateWrapper en raison de l'instruction New, mais je m'en fous parce que l'état du modèle est MVC spécifique de toute façon. En faisant cela, vous n'auriez pas besoin d'enregistrer ModelStateWrapper ou ModelState avec StructureMap.

Dans vos tests unitaires, vous pouvez appeler la méthode Initialize sur le service après avoir créé le contrôleur pour passer dans l'état de votre modèle de test et vérifier les erreurs de validation.

Je sais que vous aviez dit que vous utilisiez un ModelStateWrapper, mais je voulais juste ajouter un exemple plus complet qui pourrait aider les autres ...

+0

Même moi je suis sorti de cette façon pour résoudre le problème! Cependant, vous obtenez le point ... même si ce n'est pas exactement la solution –

0

Vous devriez vraiment éviter de telles références circulaires. Votre classe de service ne doit pas dépendre du contrôleur ou de quoi que ce soit dans l'ensemble System.Web.Mvc. C'est le rôle du contrôleur ou d'un filtre d'action ou d'un classeur de modèle de manipuler le ModelState en fonction des événements se produisant dans la couche de service.

+0

J'utilise en fait un ModelStateWrapper qui hérite d'un IErrorDictionary. Le service utilise IErrorDictionary et n'est donc pas lié à System.Web.Mvc. J'ai écrit ceci par souci de simplicité –