views:

451

answers:

2

Hello, I'm really new to Castle Windsor IoC container. I wanted to know if theres a way to store session variables using the IoC container. I was thinking something in the line of this:

I want to have a class to store search options:

public interface ISearchOptions{
    public string Filter{get;set;}
    public string SortOrder{get;set;}
}

public class SearchOptions{
    public string Filter{get;set;}
    public string SortOrder{get;set;}
}

And then inject that into the class that has to use it:

public class SearchController{
    private ISearchOptions _searchOptions;
    public SearchController(ISearchOptions searchOptions){
        _searchOptions=searchOptions;
    }
    ...
}

then in my web.config, where I configure castle I want to have something like:

<castle>
    <components>
        <component id="searchOptions" service="Web.Models.ISearchOptions, Web" type="Web.Models.SearchOptions, Web" lifestyle="PerSession" />
    </components>
</castle>

And have the IoC container handle the session object without having to explicitly access it myself.

How can I do this?

Thanks.

EDIT: Been doing some research. Basically, what I want is to have the a session Scoped component. I come from Java and Spring Framework and there I have session scoped beans which I think are very useful to store session data.

A: 

It sounds like you are on the right track, but your SearchOptions class needs to implement ISearchOptions:

public class SearchOptions : ISearchOptions { ... }

You also need to tell Windsor that your SearchController is a component, so you may want to register that in the web.config as well, although I prefer to do it from code instead (see below).

To make Windsor pick up your web.config, you should instantiate it like this:

var container = new WindsorContainer(new XmlInterpreter());

To make a new instance of SearchController, you can then simply do this:

var searchController = container.Resolve<SearchController>();

To register all Controllers in a given assembly using convention-based techniques, you can do something like this:

container.Register(AllTypes
    .FromAssemblyContaining<MyController>()
    .BasedOn<IController>()
    .ConfigureFor<IController>(reg => reg.LifeStyle.Transient));
Mark Seemann
+2  A: 

Hi, this might be what your looking for.

public class PerSessionLifestyleManager : AbstractLifestyleManager
    {
 private readonly string PerRequestObjectID = "PerSessionLifestyleManager_" + Guid.NewGuid().ToString();

 public override object Resolve(CreationContext context)
 {
  if (HttpContext.Current.Session[PerRequestObjectID] == null)
  {
   // Create the actual object
   HttpContext.Current.Session[PerRequestObjectID] = base.Resolve(context);
  }

  return HttpContext.Current.Session[PerRequestObjectID];
 }

 public override void Dispose()
 {
 }
}

And then add

<component
        id="billingManager"  
        lifestyle="custom"  
        customLifestyleType="Namespace.PerSessionLifestyleManager, Namespace"  
        service="IInterface, Namespace"
        type="Type, Namespace">
</component>
Carl Bergquist
Thanks, this is exactly what I was looking for.
Carles
Me too! Thanks.
Mr. Flibble