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 >>> >>> >>> >>> >>> >>> >>> > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---