Well, I'm torn. I've just knocked together a prototype for what is essentially Billy's design, reworked a bit. I've created an IAutoMappingConfigChunk, which has an Configure(AutoPersistenceModel model) method. You add chunks to an APM, each one gets executed before the mappings are compiled.
Leading on from that, I've created an IMappingOverride<T> interface, which has a single method of Override(AutoMap<T> mapping); this interface allows you to have the simplicity of class-per-override as the inheritance strategy, but without the nasty inheritance. IMappingOverride's are added using a custom IAutoMappingConfigChunk that takes an assembly and finds any types that derive from IMappingOverride. So i'm actually dogfooding the config stuff. http://gist.github.com/61092 - config chunk stuff http://gist.github.com/61097 - IMappingOverride<T> stuff What do you guys think? On Mon, Feb 9, 2009 at 9:36 PM, Steven Harman <stevehar...@gmail.com> wrote: > Just doing my part to keep everyone thoroughly confused and confounded! :) > > //---- 90% of being smart is knowing what you're dumb at ----// > http://stevenharman.net/ > > > On Mon, Feb 9, 2009 at 4:34 PM, James Gregory <jagregory....@gmail.com>wrote: > >> One for each then, thanks guys! :) >> >> >> On Mon, Feb 9, 2009 at 9:28 PM, Steven Harman <stevehar...@gmail.com>wrote: >> >>> Seeing this new way, I think I'd much prefer it to using inheritance. >>> I've really started to realize that inheritance is rarely the optimal >>> solution to a problem - often its simply the one we are most comfy with, and >>> so we naturally go there first. >>> >>> So, I guess what I'm saying is... I'd rather see the extension method >>> way, as it adds a nice point of extension, while allowing us to leverage >>> composition to build really dynamic and granular mapping overrides. Or at >>> least, that's my gut reaction. >>> >>> Thanks all, >>> -steve >>> >>> //---- 90% of being smart is knowing what you're dumb at ----// >>> http://stevenharman.net/ >>> >>> >>> On Mon, Feb 9, 2009 at 3:27 PM, Billy <wmccaffe...@gmail.com> wrote: >>> >>>> >>>> James, >>>> >>>> Thank you for my input on the matter; albeit, I'd like it to be >>>> perfectly known that I'm still getting my feet wet with Fluent >>>> NHibernate and have a lot to learn on the subject. Personally, I like >>>> the ability to inherit from AutoMap as it makes the behavior more >>>> interchangeable with ClassMap behavior. It also makes the mapping >>>> identical in nature to that of ClassMap without having to introduce >>>> lambdas, which I see as complicating the matter, if only slightly. >>>> Finally, it makes it easier to use inheritance to create a grouping of >>>> overridden mappings. For instance, suppose you want an >>>> AuditableAutoMap<> base class which inherits from AutoMap<> and >>>> overrides a number of conventions for any entity that is IAuditable. >>>> You could than have a concrete MyEntityMapClass which inherits from >>>> AuditableAutoMap<>, one for each IAuditable entity. This would allow >>>> you to create an "override group" if you will. >>>> >>>> With that said, there are other approaches that could be taken to >>>> simulate on override grouping via encapsulation rather than via >>>> inheritance. But it's nice to have the inheritance option, if only >>>> for organization and consistency with ClassMap. :D When it comes down >>>> to it, there are decisions that must be made for the integrity of the >>>> design; if you feel that avoiding AutoMap inheritance is in the best >>>> interest of the overall design of Fluent NHibernate, then I'm very >>>> supportive of that decision as well. >>>> >>>> Thanks for all your great work on Fluent NHibernate...it's been a big >>>> hit within S#arp Architecture. >>>> >>>> Billy McCafferty >>>> >>>> >>>> On Feb 9, 1:07 pm, James Gregory <jagregory....@gmail.com> wrote: >>>> > I think what I've been saying may have been interpreted as being more >>>> > negative or hostile than I intended it to be. My basic point was, >>>> there >>>> > isn't a bug because you aren't using a "feature" of FNH. >>>> > I'm happy for this to become a proper supported way of overriding >>>> > automappings, but for me to be expected to support it I have to >>>> actually >>>> > write coverage for it. Until I do that, it's unofficial. >>>> > >>>> > As for my stance on actually using it, as long as it's explained that >>>> they >>>> > are overrides (and as Steve said, with a decent naming convention) >>>> there's >>>> > nothing wrong with inheriting from AutoMap<T>. I'm all for SoC. >>>> > >>>> > Billy: do you prefer your new way of writing the overrides, or would >>>> you >>>> > prefer to just inherit from AutoMap? Is this new way just to avoid the >>>> bug? >>>> > >>>> > What I'm saying is: say the word and I'll make this an official >>>> feature; >>>> > then I won't moan about not supporting an unofficial feature. >>>> > >>>> > On Mon, Feb 9, 2009 at 7:29 PM, Billy <wmccaffe...@gmail.com> wrote: >>>> > >>>> > > Here's the final approach that I took to organize my overrides: >>>> > >>>> > > 1) Add an override interface to your application as follows: >>>> > >>>> > > using FluentNHibernate.AutoMap; >>>> > >>>> > > namespace SharpArch.Data.NHibernate.FluentNHibernate >>>> > > { >>>> > > /// <summary> >>>> > > /// Used by <see cref="AutoPersistenceModelExtensions" /> to add >>>> > > auto mapping overrides >>>> > > /// to <see cref="AutoPersistenceModel" /> >>>> > > /// </summary> >>>> > > public interface IAutoPeristenceModelConventionOverride >>>> > > { >>>> > > AutoPersistenceModel Override(AutoPersistenceModel model); >>>> > > } >>>> > > } >>>> > >>>> > > 2) Create an extension method, as follows, to look for every class >>>> > > which implements IAutoPeristenceModelConventionOverride, in a >>>> > > particular assembly, and apply the override to AutoPersistenceModel: >>>> > >>>> > > using FluentNHibernate.AutoMap; >>>> > > using System.Reflection; >>>> > > using System; >>>> > > using SharpArch.Core; >>>> > >>>> > > namespace SharpArch.Data.NHibernate.FluentNHibernate >>>> > > { >>>> > > /// <summary> >>>> > > /// Provides a means to override <see cref="AutoPersistenceModel" >>>> / >>>> > > > conventions with classes >>>> > > /// that implement <see >>>> > > cref="IAutoPeristenceModelConventionOverride" />. >>>> > > /// </summary> >>>> > > public static class AutoPersistenceModelExtensions >>>> > > { >>>> > > public static AutoPersistenceModel >>>> > > MapConventionOverridesFromAssemblyOf<TOverride>( >>>> > > this AutoPersistenceModel autoPersistenceModel) where >>>> > > TOverride : IAutoPeristenceModelConventionOverride { >>>> > >>>> > > Assembly assemblyToPullConventionOverridesFrom = typeof >>>> > > (TOverride).Assembly; >>>> > >>>> > > foreach (Type type in >>>> > > assemblyToPullConventionOverridesFrom.GetTypes()) { >>>> > > if (typeof >>>> > > (IAutoPeristenceModelConventionOverride).IsAssignableFrom(type)) { >>>> > > IAutoPeristenceModelConventionOverride instance = >>>> > > Activator.CreateInstance(type) as >>>> > > IAutoPeristenceModelConventionOverride; >>>> > >>>> > > if (instance != null) >>>> > > instance.Override(autoPersistenceModel); >>>> > > } >>>> > > } >>>> > >>>> > > return autoPersistenceModel; >>>> > > } >>>> > > } >>>> > > } >>>> > >>>> > > 3) Create a class for each entity that requires a convention >>>> override; >>>> > > for example: >>>> > >>>> > > using FluentNHibernate.AutoMap; >>>> > > using Northwind.Core; >>>> > > using SharpArch.Data.NHibernate.FluentNHibernate; >>>> > >>>> > > namespace Northwind.Data.NHibernateMappings >>>> > > { >>>> > > public class CustomerMap : IAutoPeristenceModelConventionOverride >>>> > > { >>>> > > public AutoPersistenceModel Override(AutoPersistenceModel >>>> > > model) { >>>> > > return model.ForTypesThatDeriveFrom<Customer>(map => { >>>> > > map.SetAttribute("lazy", "false"); >>>> > > }); >>>> > > } >>>> > > } >>>> > > } >>>> > >>>> > > 4) Include a call to the extension method when setting up the >>>> > > AutoPersistenceModel; e.g., >>>> > >>>> > > AutoPersistenceModel mappings = AutoPersistenceModel >>>> > > .MapEntitiesFromAssemblyOf<Customer>() >>>> > > ... >>>> > > .WithConvention(GetConventions) >>>> > > .MapConventionOverridesFromAssemblyOf<CustomerMap>(); >>>> > >>>> > > I'll be including this approach in the next release of S#arp >>>> > > Architecture which leverages Fluent NHibernate. Hope this helps! >>>> > >>>> > > Billy McCafferty >>>> > >>>> > > On Feb 9, 9:03 am, Steven Harman <stevehar...@gmail.com> wrote: >>>> > > > Being one of the folks currently using the AutoPersistenceModel in >>>> an >>>> > > > unconventional (or rather, just unexpected) manner, I suppose I >>>> should >>>> > > speak >>>> > > > up in favor of allowing, and suggesting, that class-specific >>>> convention >>>> > > > overrides be split out into their own auto mappings files. I'm on >>>> board >>>> > > > w/Andy - this approach keeps things more granular, better >>>> seperated, and >>>> > > > easier to grok when you have a large number of mappings. >>>> > >>>> > > > That said, I also see James concern that it might not be obvious >>>> that >>>> > > these >>>> > > > small one-off maps are actually overriding some other auto >>>> mapping, setup >>>> > > > elsewhere. However, I think some smart naming conventions, >>>> namespacing, >>>> > > and >>>> > > > a little bit of education could go a long way toward eliminating >>>> that >>>> > > > concern. But then, that's just my opinion. >>>> > >>>> > > > Perhaps talking about the various ways folks are using FNH >>>> mappings (both >>>> > > > auto and manual), and the lessons we're learning, would be a good >>>> topic >>>> > > for >>>> > > > a VAN Meeting? >>>> > >>>> > > > -steve >>>> > >>>> > > > //---- 90% of being smart is knowing what you're dumb at ----// >>>> > >http://stevenharman.net/ >>>> > >>>> > > > On Mon, Feb 9, 2009 at 9:44 AM, AndyStewart < >>>> andrewnstew...@gmail.com >>>> > > >wrote: >>>> > >>>> > > > > Hi James >>>> > >>>> > > > > I've not read the whole thread, so forgive me if I'm going in >>>> the >>>> > > > > wrong direction. However let me shed some light on this, >>>> > > > > looks like some users of the library are inheriting from AutoMap >>>> and >>>> > > > > using the model.addMappingsFromAssembly( ); method. >>>> > > > > This is in-fact the very first way I wrote automappings, until >>>> Chad >>>> > > > > showed me the light to the fluent method. However if >>>> > > > > your doing alot of custom mappins then loading in via seperate >>>> classes >>>> > > > > is a lot cleaner than the 80 lins of fluent code >>>> > > > > I have in one of my projects (yuk). >>>> > >>>> > > > > Hope you this puts you in the picture as how this has come >>>> about. >>>> > >>>> > > > > Andy >>>> > >>>> > > > > On Feb 9, 10:33 am, James Gregory <jagregory....@gmail.com> >>>> wrote: >>>> > > > > > Billy, it's important to note that I never said you shouldn't >>>> be >>>> > > deriving >>>> > > > > > from AutoMap<T>. If that works for you (or did...) then great. >>>> My >>>> > > point >>>> > > > > is >>>> > > > > > that this style of modeling has evolved without my knowledge, >>>> which >>>> > > is >>>> > > > > > interesting and concerning at the same time; if it's a good >>>> thing >>>> > > then I >>>> > > > > > have no issue with it, but I can't be seen to endorse it >>>> without >>>> > > > > > understanding the implications of it's use beforehand. >>>> > > > > > For starters, we have no tests covering this code; which leads >>>> us to >>>> > > > > > situations like this where I manage to break it for people >>>> without >>>> > > ever >>>> > > > > > knowing. We have no examples promoting this style (unless >>>> somebody's >>>> > > > > written >>>> > > > > > some I wasn't aware of), and as a result we have no way of >>>> supporting >>>> > > > > this >>>> > > > > > from a guidance perspective. >>>> > >>>> > > > > > My final disagreement with this is that I don't actually like >>>> the way >>>> > > it >>>> > > > > > feels. It looks like a ClassMap, smells like a ClassMap, but >>>> is an >>>> > > > > AutoMap. >>>> > > > > > You look at it and, unless you already know that it's an >>>> AutoMap, >>>> > > think >>>> > > > > > "where are all the other mappings?" However, that could just >>>> be me >>>> > > > > because >>>> > > > > > I'd not used it in this manner. >>>> > >>>> > > > > > All that being said, I can definitely see the merit in >>>> separating the >>>> > > > > > overrides into their own classes. People obviously like doing >>>> > > overrides >>>> > > > > in >>>> > > > > > the manner that #arch does them, so presuming I can get the >>>> code >>>> > > under >>>> > > > > test >>>> > > > > > (and fix the bug), I have no issue with people proceeding. >>>> > >>>> > > > > > I've got some time tomorrow working on FNH, so I'll take a >>>> look at >>>> > > this >>>> > > > > > then. >>>> > >>>> > > > > > On Mon, Feb 9, 2009 at 3:16 AM, Billy <wmccaffe...@gmail.com> >>>> wrote: >>>> > >>>> > > > > > > I was also inheriting from AutoMap and ran into the same >>>> exception >>>> > > > > > > with recent updates. The workaround that I've put in place >>>> for >>>> > > this >>>> > > > > > > issue for keeping overrides well organized is described at >>>> > >>>> > > >>>> http://groups.google.com/group/sharp-architecture/msg/c74d493fc74ed98. >>>> > > > > .. >>>> > > > > > > . >>>> > > > > > > Although it's within the context of S#arp Architecture, it >>>> could be >>>> > > > > > > reused in any project. >>>> > >>>> > > > > > > Billy McCafferty >>>> > >>>> > > > > > > On Feb 3, 12:13 pm, Jimit <jimitndi...@gmail.com> wrote: >>>> > > > > > > > The method MergeWithAutoMapsFromAssembly<T>() seemed to >>>> suggest >>>> > > the >>>> > > > > > > > style I used - that is, subclassing AutoMap<T> in an >>>> assembly. It >>>> > > did >>>> > > > > > > > discover my automaps fine, but then failed with the error >>>> > > described. >>>> > > > > > > > My domain has some very deep hierarchies and the fluent >>>> > > configuration >>>> > > > > > > > (using ForTypesThatDeriveFrom<T>) was getting rather wordy >>>> so I >>>> > > > > > > > seperated them into individual subclasses of AutoMap<T> >>>> and >>>> > > merged >>>> > > > > > > > them into my AutoPersistenceModel using >>>> > > > > > > > MergeWithAutoMapsFromAssembly<T>(). It seemed to work >>>> fine, until >>>> > > it >>>> > > > > > > > didn't. :) I think subclassing AutoMap<T> should be >>>> supported, >>>> > > if >>>> > > > > > > > nothing else than for consistency with ClassMap<T> for >>>> > > non-automapped >>>> > > > > > > > entities. >>>> > >>>> > > > > > > > Speaking of ForTypesThatDeriveFrom<T>, I think a >>>> non-generic >>>> > > overload >>>> > > > > > > > might come in handy. One use case (that's got me stumped >>>> at the >>>> > > > > moment >>>> > > > > > > > - having to use reflection) is setting conventions for the >>>> open >>>> > > form >>>> > > > > > > > of a generic base type, e.g EntityBase<,>. In my >>>> particular case, >>>> > > I >>>> > > > > > > > want to ignore certain properties in >>>> EntityBase<TEntity,TId> but >>>> > > > > don't >>>> > > > > > > > want to have to tell the Automapper to ignore >>>> > >>>> > ... >>>> > >>>> > read more ยป >>>> >>>> >>> >>> >>> >> >> >> > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Fluent NHibernate" group. To post to this group, send email to fluent-nhibernate@googlegroups.com To unsubscribe from this group, send email to fluent-nhibernate+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/fluent-nhibernate?hl=en -~----------~----~----~----~------~----~------~--~---