May 2006 - Posts
Have I mentioned that I like LINQ
When developing applications that use a relational database we often spend a reasonable amount of time constructing queries for retrieving the data that we need out of the database. The way by which we (as developers) go about retrieving this data varies considerably across applications. Some people build Sql Command objects and add their parameters to it, others build a query object for their O/R Mapper and pass it on through, and still others build the SQL for retrieving their objects from scratch from within their C# code.
Over the course of the last several months we’ve changed the way we query for data a number of times. In the beginning we started with hand coding expressions in string literals like so:
List<Customer> customers = repository.FindAll(“Age > 20 AND Name = ‘foo’”);
While this did the job it wasn’t ideal since if a column name changed it wouldn’t be caught at compile time. We also ended up with some logic for dealing with certain cases spread across our code base. To help reduce the duplication of code that we started having we created “criteria” objects to encapsulate that logic. Our code became something like:
Criteria c = new AndCriteria(
new PropertyCriteria(Customer.Columns.Age, 20, Operator.GreaterThan),
new PropertyCriteria(Customer.Columns.Name, “bar”)
);
List<Customer> customers = repository.FindAll(c);
This helped reduce the amount of code that was scattered across our code base and got rid of the problems that having column names within string literals introduced, however, our query became pretty verbose. The next step in the evolution of our query API was to take the best of the first approach and combine it with the best of the second approach. In the end we ended up with this:
List<Customer> customers = repository.FindAll(Customer.Columns.Age == 20 & Customer.Columns.Name == “foo”);
Now we have the nice compact syntax of the original query, nice strongly “typed” columns (via code-gen), and the benefits of having all the custom logic that happens behind the scenes encapsulated in our base criteria class (which is what gets returned as a result of the expression above). The other benefit of this approach is that it isn’t tied to any particular O/R Mapper or data access strategy. If we decide we want to move from one O/R Mapper to the other its just a matter of writing a single criteria “parser” that can translate our criteria objects into OPath, HQL, OQL, or etc. The next step in our evolution will be getting the same criteria expression to also work with the various find operations we have on in memory collections such as List<T>.FindAll().
This past week I got to experiment with securing WCF (Indigo) Operations with AzMan. We ended up with something like this:
[ServiceContract]
public class ICustomerService {
[OperationContract]
[FaultContract(typeof(OperationPermissionFault))]
[Authorization(“FindCustomer”)]
Customer FindCustomer(FindCustomerRequest request);
}
Decorating the operations on our WCF Service with an AuthorizationAttribute ensures that the user calling the service has the appropriate permission to run the operation. The AuthorizationAttribute is an operation behavior (IOperationBehavior) that injects a custom IParameterInspector into the processing pipeline for the given WCF operation. The Parameter Inspector then does an authorization check against AzMan for the user that called the service. All cool stuff.
If your interested in integrating with AzMan for authorization checkout Sam’s most excellent post on the topic entitled: “How To: STS/Windows Authentication with ADAM/AD, Roles in AzMan with WCF”.
Today I’d like to talk about a few of the extensibility points within WCF. I should note that the descriptions below are my interpretation of how each of the extensibility points are meant to be used and not guaranteed to be correct since I couldn’t find any real definitions anywhere 
During my investigation I found a couple different points of extensibility within WCF. The first extensibility point allows you to change the behavior of your services, endpoints, and operations and have the appropriate name of “Behaviors”. The second extensibility point I came across was what I’m going to refer to as “Inspectors”. Inspectors can be added to the processing pipeline of WCF and can control how messages are processed when they enter the pipeline via a request as well as when the messages go back out the other end when sending a response.
Behaviors
While investigating behaviors I came across the following three interfaces: IServiceBehavior, IEndpointBehavior, and IOperationBehavior. The astute reader among you will surely see that these three interfaces allow developers to extend the beahvior of services, endpoints, and operations! Often times the behavior is responsible for configuring “Inspectors” that will then be injected into the processing pipeline. Whether you choose a IServiceBehavior, IEndpointBehavior, or IOperationBehavior depends on the level of granularity by which you want to alter the behavior of WCF.
If you interested in changing the behavior of WCF at the service level you’ll create your own IServiceBehavior. Often times if you create a service behavior you’ll want to apply the behavior to all the endpoints within this service which is where the IEndpointBehavior comes in. If you want to be a little more fine grained you may forgo the IServiceBehavior and IEndpointBehavior in favor of the IOperationBehavior. An IOperationBehavior can be applied on a per Operation basis and are typically done so via attributes (for example the AuthorizationAttribute mentioned above).
While behaviors are the means by which you change the behavior of WCF they often times aren’t the ones doing the actual work. Enter Mr. Inspector.
Inspectors
Inspectors are how you actually change and/or alter the processing pipeline of Indigo. By creating a IDispatchMessageInspector you can pre-process messages as they enter and exit the WCF pipeline. At the IDispatchMessageInspector level you’re dealing with messages before they’ve found their final destination (aka: Operation). Often times your IServiceBehavior or IEndpointBehavior will add a custom IDispatchMessageInspector to the Dispatch Runtime of Indigo. Pre-processing of incoming messages can be done in the AfterReceiveRequest method of your IDispatchMessageInspector, while pre-processing of repy messages can be done in the BeforeSendReply method.
IDispatchMessageInspectors are typically injected into the WCF pipeline in the ApplyDispatchBehavior method of your custom IServiceBehavior or IEndpointBehavior class by adding the message inspector to the “DispatchRuntime.MessageInspectors” collection.
If your developing something more fine grained then the service or endpoint level you’ll likely be injecting IParameterInspector’s into the processing pipeline via a custom IOperationBehavior class. Once a WCF message has gone through the necessary processing and found a home (aka a matching OperationContract) you have one more chance to apply some of your own custom logic via your very own IParameterInspector. The parameter inspector allows pre and post processing of messages via the BeforeCall and AfterCall method. The BeforeCall method is called just before the message is dispatched to the service operation and the AfterCall method is called just before the response message is sent from the service operation back to the client.
In order to do our authorization checks at the operation level we created a custom IParameterInspector that calls out to AzMan and validates that the user has the necessary permissions. If the user does not have permissions we throw a OperationPermissionFault to our client which prevents the operation on the service from executing.
Wrapping Up
While this post overviews several of the extensibility points within WCF it is NOT an exhaustive list. It also doesn’t go into a whole lot of detail regarding the specifics of how all of the above is done in code. I’ll be looking to do some additional posts which detail how all of the above is done in code in the next couple of weeks. Additionally I’ll be digging into some of the extensibility points which I have not investigated thus far. If your interested in a full list of extensibility points within WCF checkout Christian Weyer WCF Extensibility Cornucopia post.
If you have any questions or would like to see sample code for something particular drop me a line and I’ll see what I can do. If your starting to work with WCF I strongly encourage you to start digging into the details of their extensibility model…it kicks ass! 
Paul has an excelent post that addresses much of the FUD that is being thrown around regarding O/R Mapping and stored procs.
I think the most interesting observation is that I know of many, myself included, that switched from these stored proc based systems to using O/RM without stored procs, but I know no one that switched the other way! Why is that? Could it possibly be that we know based on our experience, instead of idle academic guessing, that are apps are just as secure and performant as they were before O/RM, but far easier to build/maintain? And why is it that I still use stored procs when they make sense, especially for batch jobs and reports, as well as for the occasional situation where there are some serious performance optimizations to be made? Could it be that O/RM users are not anti- stored proc, but instead simply use the best tool for the job? And why do they assume we can't possibly use triggers for maintaining history -- I've recommended triggers. And if they really insist on stored procs, then why do they ignore O/RMs that do support those stored procs? It seems instead that some people must defend their decision to continue doing what they have always done, in spite of the many facts and success stories that speak differently, thus the continuing parade of FUD. Can you do things poorly with O/RM? Absolutely -- just like you can make poor choices without an O/RM!
I couldn’t have said things better myself. Thanks for the words of wisdom Paul!
Dinesh recent post, Lazy ORM users deserve it!, talks about how lazy loading can lead to performance and concurrency problems. I’m slowly coming to the conclusion that lazy loading is the root of all that people see as evil when it comes to O/R Mappers. By hiding the loading of objects from a data store behind a lazy loaded property we make the cost hidden to the end user who is utilizing our objects. It might be known that lazy loading leads to additional database hits, however, often times the scope and depth of database interaction that can result from lazy loading is not fully realized.
Many O/R Mappers support eager fetching of related objects to help reduce the amount of database interaction that is required for loading objects which are known to be required for a particular set of domain logic (See Ayende Combating the SELECT N + 1 Problem). In additional to supporting eager fetching some mappers have a caching layer that helps reduce the amount of database interaction necessary for loading the data you need. Often times it isn’t enough to prevent an innocent looking set of domain logic from causing an explosion of database hits.
So the question is...do we need to get better at using our O/R Mappers efficiently, or should our O/R Mappers make us be explicit about what we want them to retrieve and do away with lazy loading? What’s your take?
* By the way this problem isn’t unique to O/R Mappers
A leader is…
- Wise
- Intelligent
- Tactful
- Patient
- Assertive
- Passionate
- Experienced
- Creative
- Decisive
- Observant
They have…
- Character
- Integrity
- Respect
And…
- They listen.
- They empower.
- They direct.
- They guide.
- They decide.
- They criticize.
- They motivate.
- They respect.
- They think.
- They clarify.
- They encourage.
- They beleive.
And they do it because…
Great leaders help their team kick ass.
A while back I remember reading Ian Griffiths post on Expression Trees and thinking, huh?
After reading it I knew that what he was talking about was cool, I just didn’t understand it. Months later I came back to his post and can really appreciate what he’s talking about. Since the original read of his post I’ve dug into LINQ a bit more and come to understand some of the new C# 3.0 features.
Expression trees are how DLINQ will come to support more then just SQL Server. They’re also what makes DLINQ able to intelligently build targeted SQL for a given LINQ “query” (as discussed in my Getting started with LINQ post). I’ll be very interested to see how else expression trees end up being used when C# 3.0 becomes more mainstream. How much longer do we have to wait? 
A while back I remember reading Ian Griffiths post on Expression Trees and thinking, huh?
After reading it I knew that what he was talking about was cool, I just didn’t understand it. Months later I came back to his post and can really appreciate what he’s talking about. Since the original read of his post I’ve dug into LINQ a bit more and come to understand some of the new C# 3.0 features.
Expression trees are how DLINQ will come to support more then just SQL Server. They’re also what makes DLINQ able to intelligently build targeted SQL for a given LINQ “query” (as discussed in my Getting started with LINQ post). I’ll be very interested to see how else expression trees end up being used when C# 3.0 becomes more mainstream. How much longer do we have to wait? 
As most of my readers know by know I'm a bit of a O/R Mapper junkie. As such I recently was checking out a chat transcript for DLINQ on MSDN. One of the primary dev’s on DLINQ answered a question that I often hear asked when it comes to O/R Mappers and their reliance on dynamic SQL.
Matt Warren [MSFT] (Expert):
Q: And what are the most significant pros of DLinq (I mean "select where ... from ..." in C# 3.0) when compared to calling Stored Procs ?
A: This is mostly a design issue for you app. It is generally good to isolate pieces of an application from each other. Microsoft promoted SP's in the past, however, mostly for efficiency reasons, the SP's executed faster. This is no longer the case. While it is still a good design practice to isolate pieces of your app, it is not necesarily best to do that isolation at the database boundary. A product like DLINQ gives you the ability to abstract your data layer w/o losing dynamic query. The popular opinion now is to isolate application pieces at the SOA boundary.