Wenn Sie nicht wissen, wovon ich spreche, gehen Sie entweder the tutorial durch und versuchen Sie, Abhängigkeit hinzuzufügen. Spritzen Sie sich ein oder versuchen Sie Ihr Glück mit meiner Erklärung des Problems.Gibt es eine gute/richtige Methode zum Lösen des Abhängigkeitsinjektionsschleife-Problems im ASP.NET MVC ContactsManager-Lernprogramm?
Hinweis: Dieses Problem liegt nicht im Rahmen des ursprünglichen Lernprogramms zu ASP.NET. Das Lernprogramm schlägt nur vor, dass die verwendeten Muster für die Abhängigkeitsinjektion geeignet sind.
Das Problem besteht im Wesentlichen darin, dass eine Abhängigkeitsschleife zwischen dem Controller, dem ModelStateWrapper und dem ContactManagerService besteht.
- Der ContactController-Konstruktor übernimmt einen IContactManagerService.
- ContactManagerService Der Konstruktor eine IContactManagerRepository (nicht wichtig) und eine IValidationDictionary (die ModelStateWrapper Arbeitsgeräte).
- Der ModelStateWrapper-Konstruktor verwendet ein ModelStateDictionary (eine Eigenschaft namens "ModelState" auf dem Controller).
So ist die Abhängigkeit Zyklus geht so: Controller> Service> ModelStateWrapper> Controller
Wenn Sie versuchen, Dependency Injection zu dieser hinzuzufügen, wird es scheitern. Also meine Frage ist; was soll ich deswegen machen? Andere haben diese Frage gestellt, aber die Antworten sind wenige, andere, und alle scheinen irgendwie "hack-ish".
Meine aktuelle Lösung ist den IModelStateWrapper vom IService Konstruktor und füge eine Initialize-Methode stattdessen wie folgt zu entfernen:
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 ich meine Einheit-Container wie folgt konfigurieren:
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 für den Dienst vom Controller-Konstruktor manuell aufgerufen werden muss. Gibt es einen besseren Weg? Vielleicht wo ich das IValidationDictionary irgendwie in meine Einheitskonfiguration einfüge? Soll ich zu einem anderen DI-Container wechseln? Fehle ich etwas?
Ich muss zugeben, dass ich dieses Tutorial 3 mal getan haben und nicht immer ganz so weit kommen? Ist das Problem in der Quelle oder manuell nach dem Tutorial, wenn es das letztere ist, vermissen Sie wahrscheinlich einen Schritt? – BinaryMisfit
Die Frage geht über den Umfang des ursprünglichen Tutorials hinaus, das nur auf Dependency Injection hindeutete, aber nie dazu kam, zu zeigen, wie es gemacht werden sollte. Ich werde die Frage klären. – JohannesH