IOC on IValidationDictionary with Castle Windsor

2019-02-26 14:09发布

问题:

I'm new to Castle Windsor and am just using the latest version. I've created entries for my repositories which are working fine but I have one final dependency that I'm passing into my controller.

I've created a ModelStateWrapper which inherits from IValidationDictionary. The ModelStateWrapper takes a ModelStateDictionary in it's constructor so that in my code I can pass the following as an example:

IMembershipService _memSvc;
IValidationDictionary _validationService;

public AccountController()
{
    _validationService = new ModelStateWrapper(this.ModelState);
    _memSvc = new MembershipService(_validationService);
}

In my tests I can then do this using Moq:

var v = new Mock<ModelStateDictionary>();
_validationService = new ModelStateWrapper(v.Object);
_service = new MembershipService(_validationService);

I can't seem to get Castle to inject ModelState in with the ModelStateWrapper. I have no idea where to start and it seems I can't just 'ignore it' and try to manually inject as Castle is searching for dependencies and throwing me an error saying a dependency is remaining.

How do I configure Castle Windsor to use the ModelStateWrapper based off IValidationDictionary and also include ModelState as the constructor parameter?

Lloyd

回答1:

It seems like you have a circular dependency (never a good thing). You can get around it by using an Abstract Factory as described in this very similar question.

However, although you may be able to solve the problem like this, it would be better to redesign the API to make the circular dependency go away. Circular dependencies often indicate a design flaw.



回答2:

You're doing it wrong, and your wrongdoing has nothing to do with the container you're using.

Just do it like this, if you absolutely need to:

public AccountController(IValidationService service)
{
    _validationService = service;
    _memSvc = new MembershipService(_validationService); 
}

then as you're registering your component, use an OnCreate method:

container.Register(
   Component.For<AccountController>()
   .WheveverEleseYouNeedHere()
   .OnCreate((k, controller) => 
      controller.ValidationService.Init(controller.ModelState)));