Existe uma maneira boa / adequada de resolver o problema do loop de injeção de dependência no tutorial ASP.NET MVC ContactsManager?
Se você não sabe o que eu estou falando, ou atravesseo tutorial e tente adicionar dependência Injeção você mesmo ou tente sua sorte com minha explicação do problema.
Nota: Esse problema não está dentro do escopo do tutorial original no ASP.NET. O tutorial apenas sugere que os padrões utilizados são amigáveis para injeção de dependência.
O problema é basicamente que existe um loop de dependência entre o Controlador, o ModelStateWrapper e o ContactManagerService.
O constector ContactController usa um IContactManagerService.O construtor ContactManagerService usa um IContactManagerRepository(Não é importante) e um IValidationDictionary(que implementa ModelStateWrapper).O construtor ModelStateWrapper recebe um ModelStateDictionary(que é uma propriedade chamada "ModelState" no controlador).Então, o ciclo de dependência é assim: Controller> Service> ModelStateWrapper> Controller
Se você tentar adicionar injeção de dependência a isso, ele falhará. Então minha pergunta é; o que devo fazer sobre isso? Outros postaram essa pergunta, mas as respostas são poucas, diferentes, e todas parecem meio "hack-ish".
Minha solução atual é remover o IModelStateWrapper do construtor IService e adicionar um método Initialize em vez disso:
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...
}
Com essa construção, posso configurar meu contêiner de unidade assim:
public static void ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
Infelizmente isso significa que o método "Initialize" no serviço deve ser chamadomanualmente pelo construtor do controlador. Existe uma maneira melhor? Talvez onde eu de alguma forma inclua o IValidationDictionary na minha configuração de unidade? Devo mudar para outro contêiner DI? Estou esquecendo de algo?