使用CastleWindsor解决依赖关系

时间:2012-05-27 09:52:21

标签: c# .net asp.net-mvc dependency-injection castle-windsor

我是温莎城堡的新手。当涉及到依赖解析时,它在.NET MVC应用程序中运行得非常好。目前,我通过使用Construtor注入(Eg1)或属性注入(2)来解析CONTROLLERS中的依赖关系。问题是当我尝试使用属性注入解析另一个类(非控制器类)中的依赖项时,这不会自动解析(例如3)

例如1 - 解决确定!

public class HomeController : Controller
{
    private IUserRepo _userRepo;

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

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

}

例如2 - 解决确定!

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

    public HomeController()
    {
    }

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

例如3 - 不解决!

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?
   }
}

由于

2 个答案:

答案 0 :(得分:0)

您没有显示足够的代码来明确说明为什么您的依赖关系无法解决。您没有展示如何实例化类,这对于理解依赖关系是如何得到解决非常重要。

那就是说,我可以在这里做出有根据的猜测:

您的控制器正在使用控制器工厂,它通过容器(Windsor)解析每个控制器。您的ValidationRepository是以不以容器管理的其他方式创建的(例如new ValidationRepository())。为了使依赖项解析起作用,ValidationRepository需要属于与控制器相同的依赖关系链 - 换句话说,它必须是其中一个控制器的依赖关系(或依赖关系的依赖关系,因此它的一部分)依赖链)。

如果您确实手动实例化ValidationRepository(使用new),则控制器不了解该类,因此无法解析其依赖关系。尝试使ValidationRepository成为您的某个控制器上的构造函数依赖项,看看它是否有效。

答案 1 :(得分:0)

您需要确保在Windsor容器中注册IUserRepo和ValidationRepository的实例化,然后Container中的其他项(例如您的控制器)可以依赖它们,并且它们可以相互依赖。例如:

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

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

考虑到你所写的内容,看起来好像你已经完成了第一步,因为你的控制器很乐意接受IUserRepo的实例化。

一旦ValidationRepository也存在,你可以使用属性注入或构造函数注入,它都可以正常工作。

但请注意,只有从Castle Windsor容器中获取ValidationRepository实例时,这一切才有效。执行'new ValidationRepository()'会在容器外实例化它,Castle Windsor不会知道注入依赖项。理想情况下,ValidationRepository将是容器中另一个对象的依赖项,作为依赖对象的Property或Constructor Parameter。然后Castle Windsor将根据需要为您创建一个实例。

您可以执行此操作以获取完全解析了依赖项的实例:

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

其中'Container'是对Castle Windsor Container的引用,当您首先设置Container时,您可能已将其分配给某种IoC Utility类中的静态属性。

但是,这将是Service Locator Anti-pattern的一个例子,应该避免。相反,最好让控制器工厂将控制器实例化视为MVC管道的一部分,然后将所有其他必要的依赖关系作为属性或构造函数参数进行链接。例如,控制器具有ValidationRepository依赖关系,然后ValidationRepository具有IUserRepo依赖关系等。