开发者

Can someone explain how Castle Windsor is working in my app?

开发者 https://www.devze.com 2023-02-04 05:11 出处:网络
I have begun using Castle Windsor and somehow my app is all up and running but I dont really understand how its working.Don\'t refer me to the documentation as I wouldn\'t be here otherwise.

I have begun using Castle Windsor and somehow my app is all up and running but I dont really understand how its working. Don't refer me to the documentation as I wouldn't be here otherwise.

In my Global.asax.cs I have this:

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);
}

Now this is registering a new controller factory which I understand. The installation of a WindsorContainer from the current assembly I think registers all installers for example I have a repository installer. I assume that the container that is created in Global.asax is passed to the installers.

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

        container.Register(AllTypes.FromThisAssembly()
                 .Where(type => type.Name.EndsWith("Repository"))
                 .WithService.DefaultInterface()
             开发者_Python百科    .Configure(c => c.LifeStyle.PerWebRequest));
    }
}

In my controller I have created a constructor and passed in a IRepository argument. What I dont understand is how the controller accepts this argument.

Secondly as a test I created 2 repository classes that implement a IRepository. Putting a breakpoint in the controller constructor it passes in one of these classes. How do I map what class that implements IRepository should be passed to the constructor?

I also have Fluent NHibernate up and running. For the next stage I would like the IRepository to have a dependency on the ISession. How do I do that?

Thanks for your help


Since you have registered a controller factory that uses Windsor, it is the Windsor IoC container that is responsible for resolving all your controller instances as and when they are needed.

That is, when you access a URL in your MVC project that points to the action "Index" on your "HomeController" your WindsorControllerFactory will be asked, by the MVC framework, for an instance of HomeController.

If that controller has a constructor which takes an instance of IRepository and you have registered IRepository as a service with the container then Windsor will know how to satisfy the dependency of the HomeController class. Therefore it can first resolve IRepository into some concrete class, instantiate this, and pass it in as a parameter to the HomeController constructor before returning the instance of HomeController to the MVC framework.

If you need different implementations of IRepository for different purposes (i.e. a UserRepository and a ProductRepository) you could create separate interfaces for these, each of which extend IRepository, e.g.:

public interface IProfileRepository : IRepository {}

Then you can use Windsor's fluent registration API to register all concrete classes that implement IRepository, and have them registered by the specific service they provide, e.g. IProfileRepository.

If you do this, Windsor will automatically resolve all instances that implement IRepository for you without you having to write any new registration code when you add a new implementation.

As for making your repository classes depend on ISession, you can do this in a number of ways. I would recommend not letting them depend directly on a session, but rather let them depend on a class through which they can obtain the current session (so that you can share sessions between repositories). There's lots of information on why this is good practice out there on the web, just do a search.

Now, as for actually making it happen, you can either:

  • Register an instance of a class (by interface) that will retrieve a session for you with Windsor and let Windsor resolve this class as a parameter to your repository constructors.

  • Register ISession with Windsor and use a factory method to retrieve it when it is resolved.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号