简体   繁体   中英

Resolving dependencies using CastleWindsor

I am new to Castle Windsor. When it comes to dependency resolving it is working perfectly fine in a .NET MVC application. At the moment I am resolving dependencies in CONTROLLERS by either using Construtor injection (Eg1) or property injection (2). The problem is when I am trying to resolve a dependency in another class (Not a Controller Class) using property injection, this is not resolving automatically (Eg 3)

Eg 1 - RESOLVING OK!

public class HomeController : Controller
{
    private IUserRepo _userRepo;

    public HomeController(IUserRepo userRepo)
    {
       _userRepo = userRepo;
    }

    public ActionResult Show()
    {
        return View(userRepo.GetAllUsers());
    }

}

Eg 2 - RESOLVING OK!

public class HomeController : Controller
{
    public IUserRepo _userRepo {get;set;}

    public HomeController()
    {
    }

    public ActionResult Show()
    {
       return View(_userRepo.GetAllUsers());
    }
}

Eg 3 - NOT RESOLVING!

public class ValidationRepository
{
   public IUserRepo _userRepo {get;set;}

   public bool ValidateUser()
   {
        //Here _userRepo is never resolved.
        // NB: I want property injection instead of constructor injection, is there any way?
   }
}

Thanks

You are not showing enough code to definitively say why your dependency is not getting resolved. You're not showing how the classes get instantiated, which is very important in understanding how/whether dependencies get resolved.

That said, I can make an educated guess here:

Your controllers are using a controller factory which resolves each controller via the container (Windsor). Your ValidationRepository is being created in some other way that is not being managed by the container (eg new ValidationRepository() ). In order for dependency resolution to work, ValidationRepository needs to belong to the same dependency chain as your controllers--in other words, it has to be a dependency of one of the controllers (or a dependency of a dependency, and thus part of the dependency chain).

If you are indeed instantiating the ValidationRepository manually (using new ), the controller has no knowledge of the class and thus can't resolve its dependencies. Try making ValidationRepository a constructor dependency on one of your controllers and see if that works.

You need to ensure instantiations of IUserRepo and ValidationRepository are registered in your Windsor Container before other items in the Container (such as your controllers) can depend on them, and before they can depend on each other. Eg, something like:

container.Register(
            Component.For<IUserRepo>()
            .LifeStyle.Transient.
            .ImplementedBy<YourRealUserRepo>());

container.Register(
            Component.For<ValidationRepository>()
                .LifestyleTransient());

Given what you've written, it looks as though you've taken care of the first step already as your controllers are happily picking up instantiations of IUserRepo.

Once the ValidationRepository is in there too you can use either property injection or constructor injection and it will all just work.

Note, however, that this will all only work if you obtain your instance of ValidationRepository from the Castle Windsor container. Doing a 'new ValidationRepository()' will instantiate it outside of the container and Castle Windsor will not know to inject dependencies. Ideally, ValidationRepository would be a dependency of another object in the container, as a Property or Constructor Parameter of the dependent object. Then Castle Windsor will just create an instance for you as necessary.

You can do this to get hold of an instance with dependencies fully resolved:

var validationRepository = Container.Resolve<ValidationRepository>();

Where 'Container' is a reference to the Castle Windsor Container, which you may have assigned to a static property in an IoC Utility class of some kind when setting the Container up in the first place.

However, this would be an example of the Service Locator Anti-pattern , and should be avoided. Instead, it is best to let a Controller Factory look after controller instantiation as part of the MVC pipeline and then have all other necessary dependencies chaining from that, either as Properties or Constructor Parameters. Eg, A controller has a ValidationRepository dependency, then the ValidationRepository has an IUserRepo dependency, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM