Есть ли хороший / правильный способ решения проблемы цикла внедрения зависимостей в учебнике ASP.NET MVC ContactsManager?
Если вы нене знаю, что яя говорю либо пройтиучебник и попробуйте добавить инъекцию зависимости самостоятельно или попытайте счастья с моим объяснением проблемы.
Замечания: Эта проблема неt в рамках оригинального учебника по ASP.NET. Учебник только предполагает, что используемые шаблоны удобны для внедрения зависимостей.
Проблема в основном в том, что между контроллером, ModelStateWrapper и ContactManagerService существует цикл зависимости.
Конструктор ContactController принимает IContactManagerService.Конструктор ContactManagerService принимает IContactManagerRepository(не важный) и IValidationDictionary(который реализует ModelStateWrapper).Конструктор ModelStateWrapper принимает ModelStateDictionary(это свойство называетсяModelState» на контроллере).Таким образом, цикл зависимости выглядит следующим образом: Controller> Сервис> ModelStateWrapper> контроллер
Если вы попытаетесь добавить инъекцию зависимости, это не удастся. Итак, мой вопрос: что мне с этим делать? Другие опубликовали этот вопрос, но ответов немного, они разные, и все вроде как "взломать-иш».
Мое текущее решение состоит в том, чтобы удалить IModelStateWrapper из конструктора IService и вместо этого добавить метод Initialize следующим образом:
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...
}
С помощью этой конструкции я могу настроить свой контейнер Unity следующим образом:
public static void ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterTypeInHttpRequestLifetime();
container.RegisterTypeInHttpRequestLifetime();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
К сожалению, это означает, чтоИнициализировать» метод на сервисе должен быть вызванвручную конструктор контроллера. Есть ли способ лучше? Может быть, где я как-то включаю IValidationDictionary в мою конфигурацию единства? Должен ли я переключиться на другой контейнер DI? Я что-то пропустил?