Extending your existing API or legacy data classes to support LINQ
While developing LinqExtender, i have come across various scenarios that people don’t want to extent any query class or even implement any interface. Also, it is almost absurd when they have to add new extender specific attributes to their entity class. It is though not very important for people creating new provider with small codebase but with large codebase it soon becomes a pain to modify each class.
The solution is to make Extender as a container , which is people will write their logic to act on their specific entity or list of entities, also define their settings via fluent interface. To wrap it around , there is a basic ORM that comes with the extender pack and i have a made LibraryContext on top of SqlQueryContext<T>. Inside, the constructor i wrote the following code to define the extender specific settings.
5: .Property(x => x.Id).MarkAsUnique
10: .Property(x => x.Id).MapToAttribute("Bk_Id")
11: .Property(x => x.ShelveId).MapToAttribute("Shelve_Id")
12: .Property(x => x.Title).MapToAttribute("Bk_Title")
13: .Property(x => x.BookInfo).MarkToIgnore()
Note that there is a base settings that will be applied to all the common properties under my project and is a local class inherited from LinqExtender.Configruation.All. During the instantiation it will be applied to the current container instance.
Now, as i have said extender should be used a container so that there should be no strings attached. In my entity class, i can implement IQueryObject to mark it as a query class, but if not then extender should be smarter enough to implement it internally when the entity is used in LINQ query via extender query class. Actually , under the hood it dynamically creates a proxy via Reflection.Emit that has the settings and ensures IQueryObject. I will in days time come out with a open source project where i have practiced all these reflection stuffs and which i will extensively blog about , so stay tuned.
To make it more clear i have re-implemented the LINQ to Twitter post using the new extender. So few things like implementing IQueryObject and defining unique identifier is no longer required. You can get the new copy at the end of the post.
Also, before i forget, there is a tiny catch which is you can’t left the extender auto generate settings, if you are using it in medium-trust as Reflection.Emit does not work in such environment. In that case you will have to implement IQueryObject by hand and add the attributes manually to make it work so i am leaving LinqToTwitter post untouched [See bottom]. I know most of the good hosting providers these days support high trust and soon i think medium trust will become classic with dynamic proxy generation and cross domain request is becoming growing common (Just my two cents, don't want to get in war with these ;)).
In previous release you can access the Fluent implementation of Bucket just by Bucket.Instance, as it seems that i have somewhere statically stored the bucket object and the syntax bit more sexy but considering multiple threads , there is a possibility of data corruption. Therefore Bucket instance is passed to Query<T> overrides as IBucket and new syntax for Bucket.Instance follows
1: FluentBucket fluentBucket = FluentBucket.As(bucket);
2: // do your work.
Down to acknowledgement , Microsoft Germany has published two new tutorials around LinqExtender using LinqToFlickr and LinqToTwitter that also led me fix the VB method call issue and thanks Lars and Tim. In German way i would say, “Danke[Dang – ko]”. You can find the recordings in the following URLs
Finally, while we are preparing our new Sitefinity release and making some LINQ extensions, bob’s comments were helpful shaping the release as well and nonetheless all community reviews and feedbacks are great. Try the new release here.
June 7, 2009 => Correction ,Reflecton.Emit does not work in medium trust for unmanaged IL codes and possible IL that might destabilize the runtime that it finds by verifying the assembly, will show more on it in upcoming post. Added a patch of extender, this will work in medium trust with auto implementaion and fluent configuration.