Gibt es eine gute/richtige Weg zur Lösung des dependency injection-loop-problem in der ASP.NET MVC ContactsManager tutorial?

Wenn Sie nicht wissen, was ich Rede, gehen Sie entweder durch das tutorial und versuchen add dependency Injection selbst oder versuchen Sie Ihr Glück mit meiner Erklärung des Problems.

Hinweis: Dieses problem nicht im Rahmen des ursprünglichen Tutorials auf ASP.NET. Die Anleitung wird nur suggeriert, dass die Muster, die verwendet werden, sind dependency injection freundlich.

Das problem ist im Grunde, dass es eine Abhängigkeit Schleife zwischen der Steuerung, der ModelStateWrapper und die ContactManagerService.

  1. Die ContactController constuctor nimmt eine IContactManagerService.
  2. Die ContactManagerService Konstruktor nimmt eine IContactManagerRepository (nicht wichtig) und ein IValidationDictionary (die ModelStateWrapper implementiert).
  3. Die ModelStateWrapper Konstruktor nimmt einen ModelStateDictionary (das ist eine Eigenschaft, die man als "ModelState" auf dem controller).

Also die Abhängigkeit Zyklus geht wie folgt: Controller - > Service > ModelStateWrapper > Controller

Wenn Sie versuchen, hinzufügen von dependency injection auf diese, wird es scheitern. Also meine Frage ist; was soll ich dagegen tun? Andere haben geschrieben, diese Frage, aber die Antworten sind einige, verschiedene, und alle scheinen ein bisschen "hack-ish".

Meine aktuelle Lösung ist das entfernen der IModelStateWrapper aus dem IService Konstruktor und fügen Sie eine Initialize-Methode statt wie diese:

public class ContactController : Controller
{
    private readonly IContactService _contactService;

    public ContactController(IContactService contactService)
    {
        _contactService = contactService;
        contactService.Initialize(new ModelStateWrapper(ModelState));
    }

    //Class implementation...
}

public class ContactService : IContactService
{
    private IValidationDictionary _validationDictionary;
    private readonly IContactRepository _contactRepository;

    public ContactService(IContactRepository contactRepository)
    {
        _contactRepository = contactRepository;
    }

    private void Initialize(IValidationDictionary validationDictionary)
    {
        if(validationDictionary == null)
            throw new ArgumentNullException("validationDictionary");

        _validationDictionary = validationDictionary;
    }

    //Class implementation...
}

public class ModelStateWrapper : IValidationDictionary
{
    private readonly ModelStateDictionary _modelState;

    public ModelStateWrapper(ModelStateDictionary modelState)
    {
        _modelState = modelState;
    }

    //Class implementation...
}

Mit diesem Konstrukt kann ich bei der Konfiguration meines unity-container wie diese:

public static void ConfigureUnityContainer()
{
    IUnityContainer container = new UnityContainer();

    //Registrations
    container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
    container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();

    ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}

Leider bedeutet dies, dass die "Initialize" - Methode auf dem service aufgerufen werden manuell von dem controller-Konstruktor. Gibt es einen besseren Weg? Vielleicht, wo ich irgendwie gehören die IValidationDictionary in meiner Einheit-Konfiguration? Sollte ich zu einem anderen wechseln DI-container? Bin ich etwas fehlt?

  • Ich muss zugeben, dass ich dies getan haben tutorial 3-mal und noch nie über diesen? Ist das problem in der Quelle oder manuell, nach dem tutorial, wenn es das Letzte ist Ihr wahrscheinlich fehlt ein Schritt?
  • Die Frage geht über den Rahmen des ursprünglichen Tutorials, die nur angedeutet Dependency Injection aber nie kam, um zu zeigen, wie es getan werden sollte. Ich werde das klären der Frage.
InformationsquelleAutor JohannesH | 2009-09-21
Schreibe einen Kommentar