【问题标题】:Resolving dependencies using CastleWindsor使用 CastleWindsor 解决依赖关系
【发布时间】:2012-05-27 09:52:21
【问题描述】:

我是温莎城堡的新手。在解决依赖关系时,它在 .NET MVC 应用程序中运行良好。目前我正在通过使用构造函数注入(Eg1)或属性注入(2)来解决控制器中的依赖关系。问题是当我尝试使用属性注入解决另一个类(不是控制器类)中的依赖项时,这不会自动解决(例如 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?
   }
}

谢谢

【问题讨论】:

  • 如果您是 Windsor 的新手,不妨试试 Unity Dependency Injection 或 Ninject。在我看来,它们更容易。微软推荐 Plus Unity。
  • 有效点,但目前不是一个选项:/
  • 我一直觉得 Unity 非常令人沮丧。仅就文档而言,Ninject 和 Castle Windsor 遥遥领先。
  • 这些信息不足以为您提供任何明智的答案。您需要向我们展示您如何注册您的组件以及您的 ValidationRepo 是如何得到解决的。还可以查看 Windsor 的诊断信息,尤其是如果您有任何可能错误配置的组件docs.castleproject.org/Windsor.Debugger-views.ashx
  • 我遇到了同样的问题,但我无法在任何地方找到答案。这是我的问题...stackoverflow.com/questions/19327306/… 谢谢

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


【解决方案1】:

您没有显示足够的代码来明确说明您的依赖关系没有得到解决的原因。你没有展示类是如何被实例化的,这对于理解如何/是否解决依赖关系非常重要。

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

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

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

【讨论】:

    【解决方案2】:

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

    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 将是容器中另一个对象的依赖项,作为依赖对象的属性或构造函数参数。然后 Castle Windsor 会根据需要为您创建一个实例。

    您可以这样做以获取完全解决依赖关系的实例:

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

    其中“Container”是对 Castle Windsor Container 的引用,您可能在最初设置 Container 时已将其分配给某种 IoC 实用程序类中的静态属性。

    但是,这将是Service Locator Anti-pattern 的一个示例,应该避免。相反,最好让控制器工厂将控制器实例作为 MVC 管道的一部分来处理,然后将所有其他必要的依赖项链接起来,作为属性或构造函数参数。例如,一个控制器有一个 ValidationRepository 依赖,那么 ValidationRepository 有一个 IUserRepo 依赖等等。

    【讨论】:

    • 我也有类似的情况。我添加了代码来显示我如何初始化我的组件。这是我的问题...stackoverflow.com/questions/19327306/…你能帮我解决这个问题吗?周五晚上 8 点 45 分,我被这件事困住了 :(
    猜你喜欢
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2016-01-06
    • 2017-04-29
    • 2013-12-28
    • 1970-01-01
    相关资源
    最近更新 更多