Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How does an ISession get resolved for a lifecycle #31

Open
dagda1 opened this issue Dec 14, 2019 · 4 comments
Open

How does an ISession get resolved for a lifecycle #31

dagda1 opened this issue Dec 14, 2019 · 4 comments

Comments

@dagda1
Copy link

dagda1 commented Dec 14, 2019

Hi,

I have stumbled across this repo as I am trying to upgrade some old nhibernate code.

I understand that this repo is not being maintained but I wonder if you could please answer a question about how an ISession would be resolved for a lifestyle.

I can see this code in the NhibernateFacility :

RegisterSession(x, 0),
RegisterSession(x, 1),
RegisterSession(x, 2),
RegisterStatelessSession(x, 0),
RegisterStatelessSession(x, 1),
RegisterStatelessSession(x, 2),
Component.For<ISessionManager>().Instance(new SessionManager(() =>
                    {
                        var factory = Kernel.Resolve<ISessionFactory>(x.Instance.SessionFactoryKey);
                        var s = x.Instance.Interceptor.Do(y => factory.WithOptions().Interceptor(y).OpenSession()).OrDefault(factory.OpenSession());
                        s.FlushMode = flushMode;
                        return s;
                    }, Kernel.Resolve<ITransactionManager>())
                        .Named(x.Instance.SessionFactoryKey + SessionManagerSuffix)
                        .LifeStyle.Singleton))

It registers a different session and statelessession for each lifestyle.

There is a GetLifeStyle function that does this:

            switch (defaultLifeStyle)
            {
                case DefaultSessionLifeStyleOption.SessionPerTransaction:
                    if (index == 0)
                        return registration.Named(baseName + SessionPerTxSuffix).LifeStyle.PerTopTransaction();
                    if (index == 1)
                        return registration.Named(baseName + SessionPWRSuffix).LifestylePerWebRequest();
                    if (index == 2)
                        return registration.Named(baseName + SessionTransientSuffix).LifeStyle.Transient;
                    break;
                case DefaultSessionLifeStyleOption.SessionPerWebRequest:
                    if (index == 0)
                        return registration.Named(baseName + SessionPWRSuffix).LifestylePerWebRequest();
                    if (index == 1)
                        return registration.Named(baseName + SessionPerTxSuffix).LifeStyle.PerTopTransaction();
                    if (index == 2)
                        return registration.Named(baseName + SessionTransientSuffix).LifeStyle.Transient;
                    break;
                case DefaultSessionLifeStyleOption.SessionTransient:
                    if (index == 0)
                        return registration.Named(baseName + SessionTransientSuffix).LifeStyle.Transient;
                    if (index == 1)
                        return registration.Named(baseName + SessionPerTxSuffix).LifeStyle.PerTopTransaction();
                    if (index == 2)
                        return registration.Named(baseName + SessionPWRSuffix).LifestylePerWebRequest();
                    break;
                default:
                    throw new FacilityException("Unknown default life style - please file a bug report");
            }
            throw new FacilityException("Invalid index passed to GetLifeStyle<T> - please file a bug report");

You set the name because there are multiple ISession and IStatelessSesisions getting registered.

But I do not see where this name is ever referenced again to get the ISession for that lifestyle.

Could you please clarify how this works?

@haf
Copy link
Owner

haf commented Dec 15, 2019

Hi @dagda1

Fun to have you step by. This repo + nhibernate still kicks the ass of Entity Framework, so I hope that is not the target ;) I'll try to help you.

The idea of IoC is to make configuration "just work" in the current unit of work. As such, this facility lets you resolve a Func<ISession> :

https://github.com/haf/Castle.Facilities.NHibernate/blob/master/src/samples/NHibernate.ExampleConsoleApp/Program.cs#L102

This ISession is scoped appropriately. I mostly used it per-transaction back then. But otherwise, you'd normally have a session per request. Here are some docs about that: https://stackoverflow.com/questions/4010265/how-to-let-nhibernate-retry-deadlocked-transactions-when-using-session-per-reque/4957089#4957089

If you've configured it for PWR, like this test verifies works, https://github.com/haf/Castle.Facilities.NHibernate/blob/master/src/Castle.Facilities.NHibernate.Tests/LifeStyle/per_web_request_spec.cs#L56-L69 you'll have one global session for each web request (beware of deadlocks!)

@dagda1
Copy link
Author

dagda1 commented Dec 15, 2019 via email

@haf
Copy link
Owner

haf commented Dec 15, 2019

Hi there

Yes life is good. Not so .Net focused and much more f# than when we conversed the last time. Much more architecture and leading other people.

Matching the unit of work to the transaction makes sense.

Ping me if you’re ever in Stockholm and would like to grab a beer.

Henrik

@dagda1
Copy link
Author

dagda1 commented Dec 15, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants