有人可以解释一下Castle Windsor如何在我的应用程序中运行?

时间:2011-01-13 12:07:30

标签: asp.net-mvc nhibernate fluent-nhibernate inversion-of-control castle-windsor

我已经开始使用Castle Windsor,不知怎的,我的应用程序已全部启动并运行,但我真的不明白它是如何工作的。不要将我引用到文档中,否则我不会在这里。

在我的Global.asax.cs中,我有这个:

private static IWindsorContainer container;

protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();
  RegisterRoutes(RouteTable.Routes);
  BootstrapContainer();
} 

protected void Application_End()
{
  container.Dispose();
}

private static void BootstrapContainer()
{
 container = new WindsorContainer()
                .Install(FromAssembly.This());

 var controllerFactory = new WindsorControllerFactory(container.Kernel);
 ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}

现在这是注册一个我理解的新控制器工厂。我认为从当前程序集安装WindsorContainer会注册所有安装程序,例如我有一个存储库安装程序。我假设在Global.asax中创建的容器被传递给安装程序。

public class RepositoriesInstaller : IWindsorInstaller
{
     public void Install(IWindsorContainer container, IConfigurationStore store)
    {

        container.Register(AllTypes.FromThisAssembly()
                 .Where(type => type.Name.EndsWith("Repository"))
                 .WithService.DefaultInterface()
                 .Configure(c => c.LifeStyle.PerWebRequest));
    }
}

在我的控制器中,我创建了一个构造函数并传入了一个IRepository参数。我不明白的是控制器如何接受这个论点。

其次,作为测试,我创建了两个实现IRepository的存储库类。在控制器构造函数中放置一个断点,它会传递给其中一个类。如何映射实现IRepository的类应该传递给构造函数?

我也有Fluent NHibernate启动并运行。对于下一阶段,我希望IRepository依赖于ISession。我该怎么做?

感谢您的帮助

1 个答案:

答案 0 :(得分:6)

由于您已注册使用Windsor的控制器工厂,因此Windsor IoC容器负责在需要时解析所有控制器实例。

也就是说,当您访问MVC项目中指向“HomeController”上的“Index”操作的URL时,您的WindsorControllerFactory将由MVC框架询问HomeController的实例。

如果该控制器有一个构造函数,该构造函数接受IRepository 的实例,并且您已将IRepository注册为具有容器的服务,那么Windsor将知道如何满足HomeController类的依赖性。因此,它可以首先将IRepository解析为一些具体的类,实例化它,并在将HomeController的实例返回到MVC框架之前将其作为参数传递给HomeController构造函数。

如果您需要为不同目的(即UserRepository和ProductRepository)实现不同的IRepository实现,您可以为这些实现创建单独的接口,每个接口都扩展IRepository,例如:

public interface IProfileRepository : IRepository {}

然后,您可以使用Windsor的流畅注册API来注册实现IRepository的所有具体类,并让它们通过它们提供的特定服务进行注册,例如: IProfileRepository。

如果您这样做,Windsor将自动解决为您实现IRepository的所有实例,而无需在添加新实现时编写任何新的注册码。

至于使您的存储库类依赖于ISession,您可以通过多种方式执行此操作。我建议让它们直接依赖会话,而是让它们依赖于一个类,通过它可以获得当前会话(这样你就可以在存储库之间共享会话)。有很多关于为什么这是网上好习惯的信息,只需要进行搜索。

现在,至于实际发生,你可以:

  • 注册一个类的实例(通过接口),它将使用Windsor为您检索会话,并让Windsor将此类解析为存储库构造函数的参数。

  • 向Windsor注册ISession并使用工厂方法在解析时检索它。