NHibernate package dependencies

Dec 5, 2010 at 8:23 PM

Currently, all NHibernate.Core packages have a dependency to Castle.Core (formerly Castle.DynamicProxy). But NHibernate can also work with LinFu or Spring as proxy factories.
The problem isn't really forcing developers to use Castle by default, but forcing the *package dependency* upon Castle, because this way you can't install the NHibernate package *and* another package that depends on a different Castle version.

So I propose breaking this artificial dependency by creating packages NHibernate.Castle, NHibernate.LinFu, NHibernate.Spring.

Thoughts?

--
Mauricio 

Coordinator
Dec 6, 2010 at 1:53 AM

Yes, what you suggest is the recommended solution.  Packages like NHibernate.Castle, NHibernate.LinFu, NHibernate.Spring are referred to as 'meta-packages' in the sense that they only bring in dependencies but don't really have bits of their own.  Well, they may have some minimal bits that configure the various components to work together.  One good way to do this is to use the WebActivator package to auto-run the startup code (if needed, that may or may not be the case here).

Are you sort of the official maintainer of the NH packages?  If so, feel free to look at everything that's there now and rework it into more logical units as appropriate.

Dec 6, 2010 at 3:22 AM

I'm not the official NH package maintainer, I don't think there is one... These packages would have actual bits (minimal as you said, e.g. NHibernate.ByteCode.Castle.dll which is 7KB).

I have no problem doing this package split, but the problem is that NHibernate *requires one* of these three packages to work, and people won't fetch the "NHibernate.Castle" or "NHibernate.Spring" package (which would in turn fetch NHibenate.Core as dependency), but instead they'll go straight to NHibernate.Core. Regular NH users already know this but new users always trip (lots of questions like this one). 

Ideally, when installing NHibernate.Core, the package manager should show a big note telling the user that he should fetch one of these bytecode packages (if it isn't already present). The WebActivator solution seems insufficient here because:

  1. It looks like it only applies to web projects (does it?)
  2. There are lots of ways to set up NHibernate (xml, ActiveRecord, ConfORM, FluentNHibernate). If I added NHibernate through FluentNHibernate, adding NH's startup code as xml (e.g. a web.config.transform) would be wrong. And it greatly depends on what DBMS you're using and other stuff. In short, there is no good way to generalize this.

Another solution would be keeping NHibernate.Core as a "private" package, i.e. not showing it in the feed. I really don't like this solution.. just thinking aloud here.

--
Mauricio 

Coordinator
Dec 6, 2010 at 7:18 AM

Maybe 'official' was too strong a term. :)  Let's say someone who is willing to take the time to make sure that all the packages related to NH are in good shape, and it sounds like you're it!  No one on the NuGet team is an NH expert, so we definitely need people like you to step up and clean things up (as long as Fabio is ok with it all, which presumably he is).

The issue you describe basically comes down to naming.  Ok, so here is my (maybe random) suggestion:

  1. NH.Core doesn't have the Castle.Core dependency
  2. Add NHibernate.Castle, NHibernate.LinFu, NHibernate.Spring packages as we discussed
  3. Also add a package named just 'NHibernate' (or maybe 'NHibernate.Default'?), which is identical to NHibernate.Castle (it can just take a dependency on it, essentially becoming an alias to it).  The reasoning here is that beginners will just install Nhibernate (and hopefully be happy with Castle), while experienced devs will pick the one they really want.

I'd love to see a graph of all the packages that are part of the NH world.  Sounds like a pretty complex picture.  Definitely the most complex dependency graph that we have today on the NuGet feed. :0

Dec 6, 2010 at 12:41 PM
mausch wrote:
  1. There are lots of ways to set up NHibernate (xml, ActiveRecord, ConfORM, FluentNHibernate). If I added NHibernate through FluentNHibernate, adding NH's startup code as xml (e.g. a web.config.transform) would be wrong. And it greatly depends on what DBMS you're using and other stuff. In short, there is no good way to generalize this.

This is not so true, FNH and Conform supports configuration by xml (app.config, web.config or just hibernate.cfg.xml), I am not sure on AR but there must be an option to use nhibernate standard configuration mechanism.

Dec 6, 2010 at 2:44 PM
jfromaniello wrote:
mausch wrote:
  1. There are lots of ways to set up NHibernate (xml, ActiveRecord, ConfORM, FluentNHibernate). If I added NHibernate through FluentNHibernate, adding NH's startup code as xml (e.g. a web.config.transform) would be wrong. And it greatly depends on what DBMS you're using and other stuff. In short, there is no good way to generalize this.

This is not so true, FNH and Conform supports configuration by xml (app.config, web.config or just hibernate.cfg.xml), I am not sure on AR but there must be an option to use nhibernate standard configuration mechanism.

Even though they support loading an external xml config, most people don't use xml config when using FNH or ConfORM.

Dec 6, 2010 at 2:50 PM
davidebbo wrote:

Maybe 'official' was too strong a term. :)  Let's say someone who is willing to take the time to make sure that all the packages related to NH are in good shape, and it sounds like you're it!  No one on the NuGet team is an NH expert, so we definitely need people like you to step up and clean things up (as long as Fabio is ok with it all, which presumably he is).

The issue you describe basically comes down to naming.  Ok, so here is my (maybe random) suggestion:

  1. NH.Core doesn't have the Castle.Core dependency
  2. Add NHibernate.Castle, NHibernate.LinFu, NHibernate.Spring packages as we discussed
  3. Also add a package named just 'NHibernate' (or maybe 'NHibernate.Default'?), which is identical to NHibernate.Castle (it can just take a dependency on it, essentially becoming an alias to it).  The reasoning here is that beginners will just install Nhibernate (and hopefully be happy with Castle), while experienced devs will pick the one they really want.

I'd love to see a graph of all the packages that are part of the NH world.  Sounds like a pretty complex picture.  Definitely the most complex dependency graph that we have today on the NuGet feed. :0

I like this suggestion but then the problem becomes: how do you enforce that someone installing through FluentNHibernate or ConfORM gets the required bytecode package?

Here's a partial dependency graph: http://i.imgur.com/rzytR.png

Coordinator
Dec 6, 2010 at 7:27 PM
Edited Dec 6, 2010 at 7:32 PM

Yes, it's a hard problem because there are many valid combinations, and if we create a meta package for each one there will be so many that it'll be confusing.  Ideally, there would be a single entry point into getting NH related bits, with switches to make your choices.  e.g.

    get-nhibernate -bytecode [LinFu|Castle|Spring] [-Fluent] [-ActiveRecord]

bytecode would default to Castle.  You get the idea.

Technically, this could be achieved today by having one 'nhibernate installer' package which brings in such 'get-nhibernate' command (much like MvcScaffold brings in new PS commands).  But that means using two commands to install NHibernate, as you first need to bring down the installer.

We need to think through those scenarios and find ways to make them easier in the future.

Coordinator
Dec 6, 2010 at 7:54 PM

What's the most common approach to getting NHibernate? I have a gut feeling that Castle by far is way more common than LinFu and Spring. If that's the case, I think the NHibernate package should use that, but perhaps with the switch that David proposed.

Dec 6, 2010 at 8:24 PM

I don't think there are any hard numbers about it but I also think Castle is the most used bytecode provider. That is what the current NHibernate package does: it has a dependency on Castle. However, as I said the problem isn't really forcing developers to use Castle by default, but forcing the *package dependency* upon Castle, because this way you can't install the NHibernate package *and* another package that depends on a different Castle version. This is very restrictive...

Having a different command set just to install NHibernate seems... kind of onerous. I'd rather just show the user some message reminding him to install one of the bytecode packages...

 

Coordinator
Dec 6, 2010 at 9:37 PM

That might be easy to do by having an install.ps1 which outputs that message at the end. However, that doesn’t show up in the Add Package Dialog.

As for depending on Castle, would binding redirects help here? Suppose you do install Castle by default and someone else wants Castle. We do have a command “Add-BindingRedirects” which attempts to fix up binding redirects so this could in theory work (assuming Castle doesn’t have a large number of binary breaking changes each release).

In the meanwhile, another way you could handle this is to have the default NHib Core take a dependency on a ShimByteCode implementation which all it does is throw an exception telling the user to install one of the others.

Just some ideas.

Dec 6, 2010 at 10:00 PM

I'd prefer to avoid binding redirects (there might be breaking changes) but I like the other two suggestions, I'll try and implement this fake package dependency thing when I get some time.

Thanks!

Coordinator
Dec 6, 2010 at 11:03 PM
Go for the simple design.

Keep in mind that Fabio awhile ago requested that "NHibernate.Core" be renamed to just "NHibernate" although I am not sure whether this was still his opinion or not. So in your renaming, there shouldn't be a .Core anymore either.

Now if we can take a moment to go from a user perspective of NuGet. I see NHibernate. I see NHibernate.Castle. I see NHibernate.LinFu. I see NHibernate.Spring. They are all next to each other in the dialog. I click on NHibernate, in the description it says to pick one of the other three packages and not it, otherwise I may incur additional setup.

FluentNHiberate, ConfORM, and AR should be entirely separate packages that take a dependency on NHibernate.

Most likely someone isn't going to just go out and see a package and just download it to see what's going on without already having some knowledge about it. If they do, the first time they run into any issues, they are going to start googling for answers.

(sorry it's been quiet on my end lately, it's install season at work)
____
Coordinator
Dec 6, 2010 at 11:08 PM
Found the issue from Fabio: http://nupackpackages.codeplex.com/workitem/3
____
Rob
"Be passionate in all you do"

http://devlicio.us/blogs/rob_reynolds
http://ferventcoder.com
http://twitter.com/ferventcoder
Coordinator
Dec 6, 2010 at 11:21 PM
ferventcoder wrote:
FluentNHiberate, ConfORM, and AR should be entirely separate packages that take a dependency on NHibernate.

If we do this, installing FluentNHibernate will not get you working bits, as you'll be missing the ByteCode package.  I think this may come as a surprise to users.

Dec 6, 2010 at 11:28 PM
Yeah, I was going to rename it NHibernate. ".Core" doesn't make much sense.
I wouldn't rely on a package description to make the user install NHibernate.Castle instead of NHibernate. People don't read. I'd really prefer to throw this right on the user's face, since practically *all* NH newbies make this mistake.
FluentNHiberate and ConfORM already are separate packages with only NHibernate as dependency. AR still isn't on the repo, need to add a couple other packages first.
I think NuGet is an early adopters' tool right now but once it hits 1.0 and the full gallery is in place it will (hopefully) get some serious adoption, so IMHO all packages should be as newbie-friendly as possible.

Cheers,
Mauricio


On Mon, Dec 6, 2010 at 8:04 PM, ferventcoder <notifications@codeplex.com> wrote:

From: ferventcoder

Go for the simple design.

Keep in mind that Fabio awhile ago requested that "NHibernate.Core" be renamed to just "NHibernate" although I am not sure whether this was still his opinion or not. So in your renaming, there shouldn't be a .Core anymore either.

Now if we can take a moment to go from a user perspective of NuGet. I see NHibernate. I see NHibernate.Castle. I see NHibernate.LinFu. I see NHibernate.Spring. They are all next to each other in the dialog. I click on NHibernate, in the description it says to pick one of the other three packages and not it, otherwise I may incur additional setup.

FluentNHiberate, ConfORM, and AR should be entirely separate packages that take a dependency on NHibernate.

Most likely someone isn't going to just go out and see a package and just download it to see what's going on without already having some knowledge about it. If they do, the first time they run into any issues, they are going to start googling for answers.

(sorry it's been quiet on my end lately, it's install season at work)
____

Read the full discussion online.

To add a post to this discussion, reply to this email (nupackpackages@discussions.codeplex.com@discussions.codeplex.com)

To start a new discussion for this project, email nupackpackages@discussions.codeplex.com@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Coordinator
Dec 6, 2010 at 11:56 PM
I disagree with the statement people don't read. People don't read UNTIL they run into an issue. So when they run into an issue, they go back and read and realize they didn't do something right. We can make it user friendly and give all the warnings we want, but someone is going to pick the wrong thing no matter what we do. So my suggestion is not to even worry about that.

We should assume some level of participation on the part of the user. Knowing full well that they are not going to always participate on that level is fine, but let's not go to great lengths to try to please everyone, especially those that don't pay attention. IMO I've never seen a good enough benefit to weigh against the efforts to make it worth doing.

With NHibernate, we don't want to have it pointing to Castle for the reasons you suggested. So IMO, we create the NHibernate.Castle, NHibernate.LinFu, and NHibernate.Spring. Then those point to NHibernate.

We take FluentNHibernate and point it to Nhibernate.Castle. If someone doesn't like this, they can create FluentNHibernate.Castle, FNH.LinFu, and FNH.Spring. Until someone complains about it though it's really not an issue. The same with the others (ConfORM and the non-existant AR).

Not trying to be totally rude about it, but if people don't read, they won't even know they have a new PowerShell command for nhibernate-get like David was suggesting, so it still wouldn't be n00b friendly.

The classic n00b mistake on the part of NH users is when NH split to having the three options and people didn't know they had to pick one. That was my case when we upgraded to 2.1.

By the way, I'm one of the non-softies on the NuGet team, and I have lots of NH experience. :D
Coordinator
Dec 7, 2010 at 12:01 AM
By the way, I like that picture of the dependency graph... going to have to use gliffy sometime!
Dec 4, 2012 at 1:06 AM
Edited Dec 4, 2012 at 1:24 AM

Ignore me, I only just realized that that latest version of nhibernate doesn't require this proxy factory packages anymore