Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 有人能解释一下Castle Windsor在我的应用程序中是如何工作的吗?_Asp.net Mvc_Nhibernate_Fluent Nhibernate_Inversion Of Control_Castle Windsor - Fatal编程技术网

Asp.net mvc 有人能解释一下Castle Windsor在我的应用程序中是如何工作的吗?

Asp.net mvc 有人能解释一下Castle Windsor在我的应用程序中是如何工作的吗?,asp.net-mvc,nhibernate,fluent-nhibernate,inversion-of-control,castle-windsor,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.

我已经开始使用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的类应该传递给构造函数

我也有流利的NHibernate启动和运行。在下一阶段,我希望iRespository依赖于ISession。我该怎么做


感谢您的帮助

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

也就是说,当您访问MVC项目中指向“HomeController”上的操作“Index”的URL时,MVC框架将要求WindsorController工厂提供HomeController实例

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

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

public interface IProfileRepository : IRepository {}
然后,您可以使用Windsor的fluent注册API注册实现IRepository的所有具体类,并通过它们提供的特定服务(例如IProfileRepository)注册它们

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

至于让您的存储库类依赖于ISession,您可以通过多种方式实现。我建议不要让它们直接依赖于会话,而是让它们依赖于一个类,通过该类可以获得当前会话(这样您就可以在存储库之间共享会话)。网上有很多关于为什么这是一个好的实践的信息,只要搜索一下就可以了

现在,要想真正做到这一点,你可以:

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

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


非常感谢您的回答,但我有两个问题。在我的存储库安装程序中,它将注册所有存储库。出于安全考虑,我创建了两个实现相同IRepository的类。在构造器中,Windsor显然决定加入其中一个类。是什么决定了这一点,为什么它不选择另一个类?我认为最好是将存储库映射到类,而不是现在使用的一般方法。我还遵循了本教程中关于公开ISession的内容,然后在实现ISession的类中创建了一个具有ISession参数的构造函数。你认为可以接受吗?谢谢你先回答最后一个问题:是的,这很好。在我的脑海中,我认为每次解析存储库时,都会给您一个新的ISession实例(我可能错了!),这并不一定理想-您可能希望在多个存储库中共享一个ISession实例,以提高性能。我将查看是否可以找到有关此信息的链接,但总体思路是在HttpContext.Items[]中创建和存储ISession,并将该实例重新用于每个iRespository(实际上,每个web请求只有一个ISession)。并且回答您的第一个问题:Windsor将始终返回服务的第一个注册组件。如果您在两个不同的具体类中注册IRepository,它将始终选择第一个类。这就是为什么我建议为每个存储库使用不同的接口,在那里它们都实现了IRepository。这样,您就可以有一个注册语句来选择实现IRepository的所有类,并将它们注册到它们自己的服务(例如UserRepository)。要注册IRepository的所有实例,您可以使用如下代码:container.register(AllTypes.FromAssemblyName(_assemblyName).Pick()。如果(t=>t.FindInterfaces((t1,o)=>t1.Name==“IRepository”,null)。长度>0)。BasedOn(typeof(IRepository))。with service.FromInterface(typeof(IRepository))。Configure(c=>c.lifesture.Transient));