haf / Castle.Facilities.NHibernate

The NHibernate Facility supercedes NHibernateIntegration and integrates with the new Transaction support. Please read http://stackoverflow.com/questions/4010265/how-to-let-nhibernate-retry-deadlocked-transactions-when-using-session-per-reque before using, it will help you.
https://github.com/haf/Castle.Facilities.NHibernate/wiki
Apache License 2.0
15 stars 23 forks source link

How does an ISession get resolved for a lifecycle #31

Open dagda1 opened 4 years ago

dagda1 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

Hi Henrik,

Thank you very much for taking the time to answer my question.

I hope life is treating you well and I hope my questions are not too annoying.

I am back in .NET land after about 10 years and I am trying to update a codebase for an old client but most of the Castle stuff which I used to love is abandoned.

I suspect the clever Castle devs went onto pastures greener.

Please feel free to ignore my question as I am guessing you went onto pastures greener also but.....

All the castle transaction stuff looks pretty abandoned, autofx, castle.transactions, castle.services.transactions so I am trying to make this work without autofx.

It appears that NHibernate 5.0 will auto enlist transactions into the same transactionscope as it has an AutoJoinTransaction property which is true by default.

I would like to start a transactionscope in the SessionManager like a unit of work.

Do you think this makes sense? I don't think there is any point persevering with out of date dependencies, no matter how good they used to be :).

Cheers

Paul Cowan

Cutting-Edge Solutions (Scotland)

blog: http://thesoftwaresimpleton.com/ website: https://cutting.scot/

On Sun, Dec 15, 2019 at 11:20 AM Henrik Feldt notifications@github.com wrote:

Hi @dagda1 https://github.com/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 :

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!)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/haf/Castle.Facilities.NHibernate/issues/31?email_source=notifications&email_token=AAA44OCOKFYGP47QRTBEAILQYYHIDA5CNFSM4J23PFZ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG4WZ5Y#issuecomment-565800183, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA44OBCXIFLUHBAXC4K4TTQYYHIDANCNFSM4J23PFZQ .

haf commented 4 years ago

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 commented 4 years ago

i will and likewise if you are ever in glasgow On Sun, 15 Dec 2019 at 14:30, Henrik Feldt notifications@github.com wrote:

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

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/haf/Castle.Facilities.NHibernate/issues/31?email_source=notifications&email_token=AAA44ODDYHHOJX7MW5VLHRLQYY5RXA5CNFSM4J23PFZ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG42L5A#issuecomment-565814772, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA44OG3ZYYRJP26NYEU7ELQYY5RXANCNFSM4J23PFZQ .

-- Cheers

Paul Cowan

Cutting-Edge Solutions (Scotland)

blog: http://thesoftwaresimpleton.com/ website: https://cutting.scot/