Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / Internal / PropertyAccessVisitor.cs / 1407647 / PropertyAccessVisitor.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// Visitor to detect and replace access to properties // // // @owner [....] //--------------------------------------------------------------------- namespace System.Data.Services.Internal { using System.Linq.Expressions; using System.Diagnostics; using System.Collections.Generic; using System.Reflection; using System.Data.Services.Providers; ///Expression visitor class which provides recognission of property access ///This class understands all the different ways WCF Data Services can use /// to access a property value in the generated query. /// The class is meant to be inherited for expression tree processing where /// property accesses are interesting. /// Note that it assumes that the expression tree looks the way WCF Data Services generate it. /// Noticable that all the GetValue method calls get the property parameter as a /// internal abstract class PropertyAccessVisitor : ALinqExpressionVisitor { ///node. This may mean that if there were some rewrites applied /// to the tree, the class may not recognize the property accesses anymore. MethodCallExpression visit method /// The MethodCallExpression expression to visit ///The visited MethodCallExpression expression internal override Expression VisitMethodCall(MethodCallExpression m) { string propertyName = null; ResourceProperty resourceProperty = null; if ((m.Method.IsGenericMethod && m.Method.GetGenericMethodDefinition() == DataServiceProviderMethods.GetSequenceValueMethodInfo) || (m.Method == DataServiceProviderMethods.GetValueMethodInfo)) { // DataServiceProviderMethods.GetSequenceValue(object value, ResourceProperty property) // or // DataServiceProviderMethods.GetValue(object value, ResourceProperty property) ConstantExpression propertyExpression = m.Arguments[1] as ConstantExpression; Debug.Assert( propertyExpression != null && propertyExpression.Value is ResourceProperty, "We should have only calls with constant ResourceProperty values."); resourceProperty = propertyExpression.Value as ResourceProperty; propertyName = resourceProperty.Name; } else if (m.Method == OpenTypeMethods.GetValueOpenPropertyMethodInfo) { // OpenTypeMethods.GetValue(object value, string propertyName) ConstantExpression propertyExpression = m.Arguments[1] as ConstantExpression; Debug.Assert( propertyExpression != null && propertyExpression.Value is string, "We should have only calls with constant string values."); propertyName = propertyExpression.Value as string; } if (propertyName != null) { Expression operand = m.Arguments[0]; Expression result = m; if (this.ProcessPropertyAccess(propertyName, ref operand, ref result)) { if (result == null) { Debug.Assert( m.Arguments.Count == 2, "Right now all methods have 2 arguments. If it ever changes this code needs to be modified."); return Expression.Call(m.Object, m.Method, operand, m.Arguments[1]); } else { return result; } } } return base.VisitMethodCall(m); } ////// MemberExpression visit method /// /// The MemberExpression expression to visit ///The visited MemberExpression expression internal override Expression VisitMemberAccess(MemberExpression m) { if (m.Member.MemberType == MemberTypes.Property) { Expression operand = m.Expression; Expression result = m; if (this.ProcessPropertyAccess(m.Member.Name, ref operand, ref result)) { if (result == null) { return Expression.MakeMemberAccess(operand, m.Member); } else { return result; } } } return base.VisitMemberAccess(m); } ///Dervied class will override them method to process any property accesses found in the tree. /// The name of the property being accessed. /// The expression on which the property is being accessed. /// The implementation may choose to return a different expression through this ref parameter. /// If the method returns true, theis null and the method /// changed this parameter, the caller will replace the operand in the original property /// access with the new expression provided in this parameter. The way the property is accessed /// and its name remains the same. /// The entire expression of the property access. /// The implementation may choose to return a different expression through this ref parameter. /// If the method returns true and this parameter is not null the caller will replace the entire /// property access expression with the new one passed in this parameter. /// If the method returns false it means that it is not interested in this property access, /// and the processing of the tree will continue by examining the children of the property access expression. /// If the method returns true the caller looks at the returned value of ///. /// If it is not-null it will replace the entire property access expression with it. /// If it's null it will just replace the operand of the property access with the . /// If the implementation wants to skip this property access without modification it should return true /// and not modify the ref parameters. If the method returns true the caller will not continue walking the children of the property /// access expression. It's the responsibility of the implementation to do so if it requires such /// functionality. protected abstract bool ProcessPropertyAccess( string propertyName, ref Expression operandExpression, ref Expression accessExpression); } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// Visitor to detect and replace access to properties // // // @owner [....] //--------------------------------------------------------------------- namespace System.Data.Services.Internal { using System.Linq.Expressions; using System.Diagnostics; using System.Collections.Generic; using System.Reflection; using System.Data.Services.Providers; ///Expression visitor class which provides recognission of property access ///This class understands all the different ways WCF Data Services can use /// to access a property value in the generated query. /// The class is meant to be inherited for expression tree processing where /// property accesses are interesting. /// Note that it assumes that the expression tree looks the way WCF Data Services generate it. /// Noticable that all the GetValue method calls get the property parameter as a /// internal abstract class PropertyAccessVisitor : ALinqExpressionVisitor { ///node. This may mean that if there were some rewrites applied /// to the tree, the class may not recognize the property accesses anymore. MethodCallExpression visit method /// The MethodCallExpression expression to visit ///The visited MethodCallExpression expression internal override Expression VisitMethodCall(MethodCallExpression m) { string propertyName = null; ResourceProperty resourceProperty = null; if ((m.Method.IsGenericMethod && m.Method.GetGenericMethodDefinition() == DataServiceProviderMethods.GetSequenceValueMethodInfo) || (m.Method == DataServiceProviderMethods.GetValueMethodInfo)) { // DataServiceProviderMethods.GetSequenceValue(object value, ResourceProperty property) // or // DataServiceProviderMethods.GetValue(object value, ResourceProperty property) ConstantExpression propertyExpression = m.Arguments[1] as ConstantExpression; Debug.Assert( propertyExpression != null && propertyExpression.Value is ResourceProperty, "We should have only calls with constant ResourceProperty values."); resourceProperty = propertyExpression.Value as ResourceProperty; propertyName = resourceProperty.Name; } else if (m.Method == OpenTypeMethods.GetValueOpenPropertyMethodInfo) { // OpenTypeMethods.GetValue(object value, string propertyName) ConstantExpression propertyExpression = m.Arguments[1] as ConstantExpression; Debug.Assert( propertyExpression != null && propertyExpression.Value is string, "We should have only calls with constant string values."); propertyName = propertyExpression.Value as string; } if (propertyName != null) { Expression operand = m.Arguments[0]; Expression result = m; if (this.ProcessPropertyAccess(propertyName, ref operand, ref result)) { if (result == null) { Debug.Assert( m.Arguments.Count == 2, "Right now all methods have 2 arguments. If it ever changes this code needs to be modified."); return Expression.Call(m.Object, m.Method, operand, m.Arguments[1]); } else { return result; } } } return base.VisitMethodCall(m); } ////// MemberExpression visit method /// /// The MemberExpression expression to visit ///The visited MemberExpression expression internal override Expression VisitMemberAccess(MemberExpression m) { if (m.Member.MemberType == MemberTypes.Property) { Expression operand = m.Expression; Expression result = m; if (this.ProcessPropertyAccess(m.Member.Name, ref operand, ref result)) { if (result == null) { return Expression.MakeMemberAccess(operand, m.Member); } else { return result; } } } return base.VisitMemberAccess(m); } ///Dervied class will override them method to process any property accesses found in the tree. /// The name of the property being accessed. /// The expression on which the property is being accessed. /// The implementation may choose to return a different expression through this ref parameter. /// If the method returns true, theis null and the method /// changed this parameter, the caller will replace the operand in the original property /// access with the new expression provided in this parameter. The way the property is accessed /// and its name remains the same. /// The entire expression of the property access. /// The implementation may choose to return a different expression through this ref parameter. /// If the method returns true and this parameter is not null the caller will replace the entire /// property access expression with the new one passed in this parameter. /// If the method returns false it means that it is not interested in this property access, /// and the processing of the tree will continue by examining the children of the property access expression. /// If the method returns true the caller looks at the returned value of ///. /// If it is not-null it will replace the entire property access expression with it. /// If it's null it will just replace the operand of the property access with the . /// If the implementation wants to skip this property access without modification it should return true /// and not modify the ref parameters. If the method returns true the caller will not continue walking the children of the property /// access expression. It's the responsibility of the implementation to do so if it requires such /// functionality. protected abstract bool ProcessPropertyAccess( string propertyName, ref Expression operandExpression, ref Expression accessExpression); } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- odbcmetadatafactory.cs
- UIElement.cs
- DesignTimeVisibleAttribute.cs
- WebPartZone.cs
- FigureParagraph.cs
- BamlWriter.cs
- _ConnectionGroup.cs
- DefaultValueTypeConverter.cs
- DataGrid.cs
- _FtpDataStream.cs
- OpCodes.cs
- VectorValueSerializer.cs
- ControlCachePolicy.cs
- PartialList.cs
- DocumentApplicationJournalEntry.cs
- _ProxyRegBlob.cs
- ValidationErrorEventArgs.cs
- ZoneLinkButton.cs
- TraceSwitch.cs
- XpsResource.cs
- TypedLocationWrapper.cs
- DrawTreeNodeEventArgs.cs
- RestClientProxyHandler.cs
- AsyncCompletedEventArgs.cs
- ZipIOLocalFileHeader.cs
- Event.cs
- Accessors.cs
- UnsafeNativeMethods.cs
- Rectangle.cs
- TargetConverter.cs
- OdbcPermission.cs
- FormatConvertedBitmap.cs
- ArgumentException.cs
- DoubleConverter.cs
- ConnectionConsumerAttribute.cs
- Int32AnimationBase.cs
- DispatcherExceptionEventArgs.cs
- SymbolType.cs
- TextEditorSpelling.cs
- WebZone.cs
- CodeNamespaceImport.cs
- CapabilitiesAssignment.cs
- DefaultShape.cs
- sitestring.cs
- ObservableCollection.cs
- sapiproxy.cs
- PartialClassGenerationTaskInternal.cs
- DifferencingCollection.cs
- XamlUtilities.cs
- EdmPropertyAttribute.cs
- RenderingBiasValidation.cs
- panel.cs
- InternalRelationshipCollection.cs
- XmlSchemaSimpleTypeRestriction.cs
- DataContractSet.cs
- XPathDocumentBuilder.cs
- AddToCollection.cs
- TableCell.cs
- DataContext.cs
- StateDesigner.CommentLayoutGlyph.cs
- File.cs
- SamlAuthenticationClaimResource.cs
- EntityDataSourceReferenceGroup.cs
- XmlDataSource.cs
- TokenFactoryCredential.cs
- ToolStripSystemRenderer.cs
- AnimationException.cs
- DesignerImageAdapter.cs
- RefType.cs
- ServiceEndpointAssociationProvider.cs
- listitem.cs
- COAUTHIDENTITY.cs
- DataGridViewTopRowAccessibleObject.cs
- StringFreezingAttribute.cs
- documentsequencetextpointer.cs
- UIPermission.cs
- DynamicRendererThreadManager.cs
- SqlConnectionHelper.cs
- StubHelpers.cs
- AttachedPropertyBrowsableAttribute.cs
- Frame.cs
- TextReader.cs
- ContextTokenTypeConverter.cs
- SafeNativeMethods.cs
- CursorConverter.cs
- DeviceContexts.cs
- VSWCFServiceContractGenerator.cs
- ProtocolsConfiguration.cs
- SHA1.cs
- XmlnsDefinitionAttribute.cs
- _NegoState.cs
- MemberRelationshipService.cs
- IMembershipProvider.cs
- RootProfilePropertySettingsCollection.cs
- TraceInternal.cs
- Pkcs9Attribute.cs
- GetIndexBinder.cs
- HttpResponseHeader.cs
- HijriCalendar.cs
- GB18030Encoding.cs