Hi Paul I will be applying your patch as the first fix for the problem, however I've just not had any time yet. I may at somepoint look for a larger refactoring, but I think one way or another dropping down your method will be essential at somepoint in the process.
Cheers Andy On Tue, Aug 26, 2008 at 9:04 PM, Paul Batum <[EMAIL PROTECTED]> wrote: > Hey Andy, > > I was wondering if you have decided where to go with this code? I thought > my patch would be a good option if you don't want to engage in a larger > refactoring. > > Paul Batum > > > On Sun, Aug 17, 2008 at 6:20 PM, Paul Batum <[EMAIL PROTECTED]> wrote: > >> Hey Andy, >> >> I decided to tackle your problem from a different angle to Chad. It sounds >> like Chad went to the root of the problem by making non generic methods. I >> came up with a less fragile way of invoking the generic methods using >> reflection. My solution replaces this: >> >> // Merge Mappings together >> var findAutoMapMethod = typeof(AutoMapper).GetMethod("MergeMap"); >> var genericfindAutoMapMethod = findAutoMapMethod.MakeGenericMethod(obj); >> genericfindAutoMapMethod.Invoke(autoMap, new[] { mapping }); >> >> With this: >> >> InvocationHelper.InvokeGenericMethodWithDynamicTypeArguments( >> autoMap, a => a.MergeMap<object>(null), new[] { mapping }, >> obj); >> >> Here is the implementation of that method: >> >> public static object >> InvokeGenericMethodWithDynamicTypeArguments<T>(T target, Expression<Func<T, >> object>> expression, object[] methodArguments, params Type[] typeArguments) >> { >> var methodInfo = ReflectionHelper.GetMethod(expression); >> if (methodInfo.GetGenericArguments().Length != >> typeArguments.Length) >> throw new ArgumentException( >> string.Format("The method '{0}' has {1} type >> argument(s) but {2} type argument(s) were passed. The amounts must be >> equal.", >> methodInfo.Name, >> methodInfo.GetGenericArguments().Length, >> typeArguments.Length)); >> >> return methodInfo >> .GetGenericMethodDefinition() >> .MakeGenericMethod(typeArguments) >> .Invoke(target, methodArguments); >> } >> >> This is sturdier because a refactoring of the MergeMap method would flow >> to the lambda. Obviously it is still somewhat fragile because there is no >> guarantee that the right number of type arguments is passed, hence the >> runtime check. >> >> The patch is attached to this email. I figure that you will probably want >> to go down the path that Chad followed, but perhaps this implementation will >> be useful trick when you don't have the luxury of modifying the API to be >> non-generic. >> >> Paul Batum >> >> >> >> On Sun, Aug 17, 2008 at 3:28 PM, Andrew Stewart < >> [EMAIL PROTECTED]> wrote: >> >>> Hi Chad >>> >>> >>>> Will this be called directly by people, or is this mostly internal API >>>> stuff? >>> >>> >>> The crappy code is only internal and tests should now fail if it's >>> broken, which is nice to know. I think I know what you mean and I'll try and >>> tidy that code up shortly, thanks for the offer to pair over this it may >>> come in useful, but i'd like to have a go at it myself for now. I'll give >>> you a shout if I get stuck though, if it's ok with you. >>> >>> Cheers >>> >>> Andy >>> >>> >>> On Sat, Aug 16, 2008 at 1:02 AM, Chad Myers <[EMAIL PROTECTED]>wrote: >>> >>>> I did a spike and got my head around it. Basically, you have a bunch >>>> of generic methods and then you're treating them non-generically. >>>> >>>> >>>> >>>> Will this be called directly by people, or is this mostly internal API >>>> stuff? >>>> >>>> >>>> >>>> I was able to create an IAutoMap rather than have AutoMap<T>, >>>> IAutoPartMapper instead of the various part mappers (IAutoMapper was >>>> confusing because there's an AutoMapper<T>, but it wasn't an IAutoMapper, >>>> IAutoMapper is really something like IAutoPartMapper, etc). >>>> >>>> >>>> >>>> Anyhow, if you use interfaces for these things and make them non-generic >>>> (i.e. don't make it Foo<T>, just make methods like Foo(Type theType)). >>>> >>>> >>>> >>>> Make the people-facing fluent interfaces generic <T>, but all the >>>> internal stuff non-generic otherwise your life will be very painful (as >>>> you've already found out). >>>> >>>> >>>> >>>> I don't want to commit my spike code because it's not tested and it's >>>> sloppy, but maybe we can pair on this sometime if you want, or if you want >>>> to research this yourself, etc. >>>> >>>> >>>> >>>> -c >>>> >>>> >>>> >>>> *From:* fluent-nhibernate@googlegroups.com [mailto: >>>> [EMAIL PROTECTED] *On Behalf Of *Andrew Stewart >>>> *Sent:* Friday, August 15, 2008 7:51 AM >>>> *To:* fluent-nhibernate@googlegroups.com >>>> *Subject:* [fluent-nhib] Re: Ayende on Fluent nHibernate - AutoMap >>>> >>>> >>>> >>>> Hello >>>> >>>> >>>> >>>> I've just checked this in and it seems to work, >>>> >>>> >>>> >>>> var persistenceModel = new >>>> AutoPersistenceModel(Assembly.GetAssembly(typeof(PlotMap))); >>>> persistenceModel.AddEntityAssembly(Assembly.GetAssembly(typeof >>>> (Address)), t => (t.Namespace == "Mdis.Entities" && ( t.BaseType == >>>> typeof(object)))); >>>> persistenceModel.Configure(cfg); >>>> >>>> >>>> >>>> The first assembly is the assembly containing your maps, the second is >>>> the assembly containing your entities (I'm assuming you have two assemblies >>>> for SoC, but there's no reason why these can't be the same). Then I've >>>> created an AutoMap which inherits from ClassMap, this is so I don't dirty >>>> up >>>> the base class with my little requirements, essentially what properties >>>> have >>>> already been mapped(to prevent duplication). >>>> >>>> >>>> >>>> Example >>>> >>>> public class PlotMap : AutoMap<Plot> >>>> { >>>> public PlotMap() >>>> { >>>> HasManyToMany<Service>(p => p.Services); >>>> } >>>> } >>>> >>>> What happens is, first it loads in your automap's then in maps in extra >>>> unmapped properties and entities(hope that makes sense). So you only need >>>> to >>>> specify exceptions to the rule everything else will be mapped straight out >>>> the box as if by magic. Now my next challenge will be making this a bit >>>> more >>>> fluent and specifying conventions across the board as of Chad's suggestion >>>> below: >>>> >>>> >>>> >>>> var model = AutoPersistenceModel >>>> .MapEntitiesFromAssemblyOf<AutoMapTests>() >>>> .Where(t => t.Namespace == "FluentNHibernate.AutoMap.Test") >>>> .ForTypesThatDeriveFrom<DomainEntity>(map => >>>> { >>>> >>>> map.UseIdentityForKey(e => e.Id, "Id"); >>>> }); >>>> >>>> >>>> >>>> Plus if anyone can think of a nice way to replace the contents of >>>> AutoPersistanceModel.AddEntityAssembly, which strict typing let me know. >>>> >>>> >>>> >>>> Hope you like it, so far. >>>> >>>> >>>> >>>> Andy >>>> >>>> >>>> >>>> >>>> >>>> >> > > > > -- ================= I-nnovate Software - Bespoke Software Development, uk wirral. http://www.i-nnovate.net --~--~---------~--~----~------------~-------~--~----~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/fluent-nhibernate?hl=en -~----------~----~----~----~------~----~------~--~---