0

i running into this situation. I see many developers here are facing similar scenarios but there are still a couple of details i would like to point out.

I have the typical situation where i have a collection of child objects. I am adding more contacts to an user.contacts property. In my mapping lazy=true on that property. I never leave the scope of the method calling the repository.

I am using Windsor WCF Facility. It was my understanding that, based on my configuration, sessions were going to live either for the life of the request, or the WcfSession.

Ask me any question if you need more info.

Here is my global.asax in my wcf service.

container = new WindsorContainer();

            container.AddFacility<AutoTxFacility>();
            container.Register(Component.For<INHibernateInstaller>().ImplementedBy<NHibernateInstaller>());
            container.AddFacility<NHibernateFacility>();
            container.AddFacility<WcfFacility>();

            container.Register(
                Component.For<IRegistrationService>().ImplementedBy<RegistrationService>().LifestylePerWcfSession(),
                Component.For<IAuthService>().ImplementedBy<AuthService>().LifestylePerWcfSession(),
                Component.For<IUserRepository>().ImplementedBy<UserRepository>().LifestylePerWcfSession(),
                Component.For<IActionWebService>().ImplementedBy<ActionWebService>().Named("ActionWebService").LifestylePerWcfSession(),
                Component.For<ISession>().LifeStyle.Singleton.UsingFactoryMethod(x => container.Resolve<ISessionManager>().OpenSession()));

Here is my repository...

public class UserRepository: IUserRepository
    {
        Func<ISession> session;

        public UserRepository(Func<ISession> _session)
        {
            session = _session;
        }

        [Transaction]
        public void Store(User user)
        {
            using (var tx = session())
            {
                tx.SaveOrUpdate(user);
            }
        }

        [Transaction]
        public User GetById(int id)
        {
            using (var tx=session())
            {
                return tx.Get<User>(id);
            }
        }
    }

Here is my call to the repository

public void AddContactsToUser(int userID, IList<User> contacts)
        {
            var user = userRepository.GetById(userID);

            if (user == null)
                throw new Exception("User does not exist");

            user.AddReferralToUser(contacts.ToArray());

            userRepository.Store(user);
        }

This is where i get the error about Session being closed.

Thank you in advance.

Pepito Fernandez
  • 2,352
  • 6
  • 32
  • 47

1 Answers1

0

You set lifestyle Singleton on the ISession. This seems maybe inconsistent with your error, but shouldn't this be ...LifeStyle.PerWcfSession()... or PerWcfOperation()?

What does the session function do? (As a side note, a common convention is to have _xxx as instance members, and xxx as function parameters.)

If you truly have the same session throughout, the call to Store/SaveOrUpdate is useless, since the object is already tracked by the session.

You have Transaction on the repository methods. This is not a problem, but for the transaction to be useful, the entire AddContactsToUser() (or more) should be executed within the same transaction.

Oskar Berggren
  • 5,583
  • 1
  • 19
  • 36
  • Hello Oskar. Thanks for your time. When I tried to set the lifestyle to PerWcfOperation i ended up asking this question http://stackoverflow.com/questions/13611697/the-factory-was-disposed-and-can-no-longer-be-used-nhibernatefacility So i decided to set it to whatever value would work at the time, and that seemed to be Singleton. I know for a fact my whole implementation is not the right one, but i haven't found a strong article out there talking about these facilities working together. – Pepito Fernandez Dec 27 '12 at 21:34
  • Regarding the Transaction attribute in the repository, it was my understanding that you want to have a transaction per operation. If I set the transaction in my application service (the one that calls the repo) then, do i have to inject the session there? This is the only guide i found about to implement the facility. https://github.com/haf/Castle.Facilities.NHibernate/wiki/NHibernate-Facility---Quick-Start What would you suggestion be in this case? Thanks – Pepito Fernandez Dec 27 '12 at 21:36