IOC on IValidationDictionary with Castle Windsor
Asked Answered
B

2

2

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

Betz answered 16/1, 2010 at 10:51 Comment(0)
C
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.

Claque answered 16/1, 2010 at 11:1 Comment(2)
So would my Account Controller look like: IMembershipService _memSvc; IValidationDictionary _validationService; public AccountController(IValidationDictionaryFactory validationDFactory) { validationDFactory.Create(this); } If so how would I run this in a test with a mocked modelstate? Sorry, if these are stupid questions, I'm only a day old on Dependency Injection.Betz
The easiest approach to DI is to use Constructor Injection whenever you can, so inject all dependencies through the constructor. This will also let you replace them with Test Doubles when necessary. Abstract Factory is a solution when you don't have the dependency at wire-up time. There may be many reasons for that.Claque
S
0

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)));
Serrated answered 16/1, 2010 at 13:9 Comment(2)
If I've got about 8 controllers am I going to have to register each controller like this to inject the modelstate?Betz
Ok, think I'm getting myself confused here. If I've registered my Interfaces in the web.config do I then use this code in the WindsorControllerFactory? Sorry, I don't think I'm understanding this very well. :)Betz

© 2022 - 2024 — McMap. All rights reserved.