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?

questionAnswers(3)

yourAnswerToTheQuestion