3
votes

I'm new to the whole castle Windsor, Nhibernate, Fluent and Automapping stack so excuse my ignorance here. I didn't want to post another question on this as it seems there are already a huge number of questions that try to get a solution the Windsor nhib Isession management problem, but none of them have solved my problem so far. I am still getting a ISession is closed exception when I'm trying to call to the Db from my Repositories,Here is my container setup code.

container.AddFacility<FactorySupportFacility>()
            .Register(
                Component.For<ISessionFactory>()
                    .LifeStyle.Singleton
                    .UsingFactoryMethod(() => Fluently.Configure()
                                                  .Database(
                                                      MsSqlConfiguration.MsSql2005.
                                                          ConnectionString(
                                                              c => c.Database("DbSchema").Server("Server").Username("UserName").Password("password")))
                                                  .Mappings
                                                     (
                                                      m => 
                                                      m.AutoMappings.Add
                                                        (
                                                          AutoMap.AssemblyOf<Message>(cfg)
                                                          .Override<Client>(map =>
                                                          {
                                                              map.HasManyToMany(x => x.SICCodes).Table("SICRefDataToClient");
                                                          })
                                                          .IgnoreBase<BaseEntity>()
                                                          .Conventions.Add(DefaultCascade.SaveUpdate())
                                                          .Conventions.Add(new StringColumnLengthConvention(),new EnumConvention())
                                                          .Conventions.Add(new EnumConvention())

                                                          .Conventions.Add(DefaultLazy.Never())
                                                        )
                                                      )
                                                  .ExposeConfiguration(ConfigureValidator)
                                                  .ExposeConfiguration(BuildDatabase)
                                                  .BuildSessionFactory() as SessionFactoryImpl),
                 Component.For<ISession>().LifeStyle.PerWebRequest.UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>().OpenSession()
                                                  ));

In my repositories i inject private readonly ISession session; and use it as followes

 public User GetUser(int id)
    {
        User u;

            u = session.Get<User>(id);
            if (u != null && u.Id > 0)
            { 
                NHibernateUtil.Initialize(u.UserDocuments);
            }


        return u;

in my web.config inside <httpModules>. i have also added this line

      <add name="PerRequestLifestyle" 
type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/>

I'm i still missing part of the puzzle here, i can't believe that this is such a complex thing to configure for a basic need of any web application development with nHibernate and castle Windsor.

I have been trying to follow the code here windsor-nhibernate-isession-mvc and i posted my question there as they seemed to have the exact same issue but mine is not resolved.

UPDATE MooKid8000 i have now updated my castle register code to this

private void AddRepositories()
    {
        container.Register(
            AllTypes.FromAssembly(typeof(MembershipRepository).Assembly)
                .Pick()
                .Configure(c => c.Interceptors(
                    InterceptorReference.ForKey("simpleLogger")).Anywhere
                )
                .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
                .WithService.FirstInterface());
    }

But I'm still getting the ISession is closed issue, Do my services need to be registered as Transient as well, Can you explain in more detail why they should be transient and not singleton's

UPDATE MooKid8000 suggestion was 100% correct , I just need to make sure my services and repositories where all scoped as LifestyleType.Transient so the ISession wasn't wiped out. Great spot Mookid8000 without even seeing my castle registration code initially.

For anybody that is intrested contact me and i can send you my container setup.

1
You may be interested in going through Windsor tutorial which uses ASP.NET MVC and NHibernate and is targeted at people with no prior experience with Windsor or IoC concepts. stw.castleproject.org/… Don't forget to share your feedback about the tutorial if anything is not clear, something is confusing, or not explained well enough - Krzysztof Kozmic
Fluent syntax at it's worst. I'm not even going to attempt to read what that codes trying to do. Sorry. - Phill
I will check this out in detail later where was this when i was searchiing for hours on end the last few weeks for a such an asp.net mvc 3 example - Simon
Phil yes it hard to follow whats going on, i was following on from help i received setting up the project this way, the fluent hibernate code works well albeit its dirty looking, the issue is that my ISession is not getting created per request and injected into the repository, it's always closed - Simon

1 Answers

5
votes

Did you remember to register your repositories with a transient lifestyle?

If your repositories are singletons (which is the default lifestyle with Windsor), then the injected ISession instance will be "caught", resulting in closed session errors later on.

Note that any services using your repositories must also have a transient lifestyle, as well as any services using those services, and so on.

Generally, you could say that the lifestyle granularity should not increase as you go further away from the composition root, otherwise some kind of scoping will happen. Of course this is not always a problem, but it can lead to errors that are pretty hard to diagnose.