Se non si sa di cosa sto parlando o passare attraverso the tutorial e provare ad aggiungere dipendenza Injection da soli o tentare la fortuna con la mia spiegazione del problema.Esiste un modo corretto/corretto per risolvere il problema del ciclo di iniezione delle dipendenze nell'esercitazione ContactsManager di ASP.NET MVC?
Nota: Questo problema non rientra nell'ambito del tutorial originale su ASP.NET. Il tutorial suggerisce solo che i pattern utilizzati sono dipendenti dall'iniezione.
Il problema è fondamentalmente che esiste un ciclo di dipendenza tra il controller, ModelStateWrapper e ContactManagerService.
- Il conduttore ContactController accetta un IContactManagerService.
- Il costruttore ContactManagerService prende un IContactManagerRepository (non importante) e un IValidationDictionary (che implementa ModelStateWrapper).
- Il costruttore ModelStateWrapper accetta un ModelStateDictionary (che è una proprietà denominata "ModelState" sul controller).
così il ciclo di dipendenza è questa: controller> Servizio> ModelStateWrapper> Regolatore
Se si tenta di aggiungere l'iniezione di dipendenza a questo, fallirà. Quindi la mia domanda è; cosa dovrei fare al riguardo? Altri hanno postato questa domanda, ma le risposte sono poche, diverse e sembrano tutte un po '"hack-ish".
La mia soluzione attuale è quella di rimuovere l'IModelStateWrapper dal costruttore IService e aggiungere un metodo Initialize invece in questo modo:
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...
}
Con questo costrutto posso configurare il mio contenitore di unità in questo modo:
public static void ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
Sfortunatamente ciò significa che il metodo "Inizializza" sul servizio deve essere chiamato manualmente dal costruttore del controllore. C'è un modo migliore? Forse dove in qualche modo includo il IVidationDictionary nella mia configurazione di unità? Devo passare a un altro contenitore DI? Mi sto perdendo qualcosa?
Devo ammettere che ho fatto questo tutorial 3 volte e non abbia mai incontrato questo? Il problema è nell'origine o segue manualmente il tutorial, se è quest'ultimo che probabilmente manca un passaggio? – BinaryMisfit
La domanda va oltre lo scopo del tutorial originale che ha solo accennato a Dependency Injection, ma non è mai arrivato a mostrare come dovrebbe essere fatto. Chiarirò la domanda – JohannesH