Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / Data / DynamicObjectAccessor.cs / 1305600 / DynamicObjectAccessor.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: Accessors for dynamic objects // //--------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Dynamic; // GetMemberBinder, etc. using System.Reflection; // PropertyInfo, etc. using System.Runtime.CompilerServices; // CallSite using System.Linq.Expressions; // Expression using SW = System.Windows; // SRID, SR namespace MS.Internal.Data { #region DynamicObjectAccessor internal class DynamicObjectAccessor { public DynamicObjectAccessor(Type ownerType, string propertyName) { _ownerType = ownerType; _propertyName = propertyName; } public Type OwnerType { get { return _ownerType; } } public string PropertyName { get { return _propertyName; } } public bool IsReadOnly { get { return false; } } public Type PropertyType { get { return typeof(object); } } Type _ownerType; string _propertyName; } #endregion DynamicObjectAccessor #region DynamicPropertyAccessor internal class DynamicPropertyAccessor : DynamicObjectAccessor { public DynamicPropertyAccessor(Type ownerType, string propertyName) : base(ownerType, propertyName) { } public object GetValue(object component) { if (_getter == null) { var binder = new TrivialGetMemberBinder(PropertyName); _getter = CallSite>.Create(binder); } return _getter.Target(_getter, component); } public void SetValue(object component, object value) { if (_setter == null) { var binder = new TrivialSetMemberBinder(PropertyName); _setter = CallSite >.Create(binder); } _setter.Target(_setter, component, value); } CallSite > _getter; CallSite > _setter; } #endregion DynamicPropertyAccessor #region DynamicIndexerAccessor internal class DynamicIndexerAccessor : DynamicObjectAccessor { private DynamicIndexerAccessor(int rank) : base(typeof(IDynamicMetaObjectProvider), "Items") { var getBinder = new TrivialGetIndexBinder(rank); var setBinder = new TrivialSetIndexBinder(rank); Type delegateType, callsiteType; MethodInfo createMethod; FieldInfo targetField; Type[] typeArgs; int i; // getter delegate type: Func typeArgs = new Type[rank+3]; typeArgs[0] = typeof(CallSite); for (i=1; i<=rank+2; ++i) { typeArgs[i] = typeof(object); } delegateType = Expression.GetDelegateType(typeArgs); // getter CallSite: CallSite >.Create(getBinder) callsiteType = typeof(CallSite<>).MakeGenericType(new Type[]{ delegateType }); createMethod = callsiteType.GetMethod("Create", new Type[]{ typeof(CallSiteBinder) }); _getterCallSite = (CallSite)createMethod.Invoke(null, new object[]{ getBinder }); // getter delegate: _getterCallSite.Target targetField = callsiteType.GetField("Target"); _getterDelegate = (MulticastDelegate)targetField.GetValue(_getterCallSite); // setter delegate type: Action typeArgs = new Type[rank+4]; typeArgs[0] = typeof(CallSite); typeArgs[rank+3] = typeof(void); for (i=1; i<=rank+2; ++i) { typeArgs[i] = typeof(object); } delegateType = Expression.GetDelegateType(typeArgs); // setter CallSite: CallSite >.Create(setBinder) callsiteType = typeof(CallSite<>).MakeGenericType(new Type[]{ delegateType }); createMethod = callsiteType.GetMethod("Create", new Type[]{ typeof(CallSiteBinder) }); _setterCallSite = (CallSite)createMethod.Invoke(null, new object[]{ setBinder }); // setter delegate: _setterCallSite.Target targetField = callsiteType.GetField("Target"); _setterDelegate = (MulticastDelegate)targetField.GetValue(_setterCallSite); } public object GetValue(object component, object[] args) { int rank = args.Length; object[] delegateArgs = new object[rank + 2]; delegateArgs[0] = _getterCallSite; delegateArgs[1] = component; Array.Copy(args, 0, delegateArgs, 2, rank); return _getterDelegate.DynamicInvoke(delegateArgs); } public void SetValue(object component, object[] args, object value) { int rank = args.Length; object[] delegateArgs = new object[rank + 3]; delegateArgs[0] = _setterCallSite; delegateArgs[1] = component; Array.Copy(args, 0, delegateArgs, 2, rank); delegateArgs[rank + 2] = value; _setterDelegate.DynamicInvoke(delegateArgs); } // ensure only one accessor for each rank public static DynamicIndexerAccessor GetIndexerAccessor(int rank) { if (_accessors.Length < rank || _accessors[rank-1] == null) { lock(_lock) { if (_accessors.Length < rank) { DynamicIndexerAccessor[] newAccessors = new DynamicIndexerAccessor[rank]; Array.Copy(_accessors, 0, newAccessors, 0, _accessors.Length); _accessors = newAccessors; } if (_accessors[rank-1] == null) { _accessors[rank-1] = new DynamicIndexerAccessor(rank); } } } return _accessors[rank-1]; } CallSite _getterCallSite, _setterCallSite; MulticastDelegate _getterDelegate, _setterDelegate; static DynamicIndexerAccessor[] _accessors = new DynamicIndexerAccessor[1]; static object _lock = new object(); } #endregion DynamicIndexerAccessor #region Trivial binders internal class TrivialGetMemberBinder : GetMemberBinder { public TrivialGetMemberBinder(string propertyName) : base(propertyName, false /*ignoreCase*/) { } public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) { return errorSuggestion ?? TrivialBinderHelper.ThrowExpression(SW.SR.Get(SW.SRID.PropertyPathNoProperty, target, Name), ReturnType); } } internal class TrivialSetMemberBinder : SetMemberBinder { public TrivialSetMemberBinder(string propertyName) : base(propertyName, false /*ignoreCase*/) { } public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { return errorSuggestion ?? TrivialBinderHelper.ThrowExpression(SW.SR.Get(SW.SRID.PropertyPathNoProperty, target, Name), ReturnType); } } internal class TrivialGetIndexBinder : GetIndexBinder { public TrivialGetIndexBinder(int rank) : base(new CallInfo(rank)) { } public override DynamicMetaObject FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion) { return errorSuggestion ?? TrivialBinderHelper.ThrowExpression(SW.SR.Get(SW.SRID.PropertyPathNoProperty, target, "Items"), ReturnType); } } internal class TrivialSetIndexBinder : SetIndexBinder { public TrivialSetIndexBinder(int rank) : base(new CallInfo(rank)) { } public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { return errorSuggestion ?? TrivialBinderHelper.ThrowExpression(SW.SR.Get(SW.SRID.PropertyPathNoProperty, target, "Items"), ReturnType); } } internal static class TrivialBinderHelper { public static DynamicMetaObject ThrowExpression(string message, Type returnType) { return new DynamicMetaObject( Expression.Throw( Expression.New( typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) }), Expression.Constant(message) ), returnType ), BindingRestrictions.Empty ); } } #endregion Trivial binders } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DictionarySectionHandler.cs
- AstNode.cs
- LabelLiteral.cs
- httpstaticobjectscollection.cs
- ProvidersHelper.cs
- HttpClientCertificate.cs
- _NestedSingleAsyncResult.cs
- HtmlLink.cs
- TableSectionStyle.cs
- TrackingWorkflowEventArgs.cs
- DataRelationPropertyDescriptor.cs
- ComboBoxAutomationPeer.cs
- ItemChangedEventArgs.cs
- FunctionImportMapping.cs
- AddressingProperty.cs
- TypeBuilder.cs
- ConfigXmlWhitespace.cs
- UnionCqlBlock.cs
- MappingModelBuildProvider.cs
- DataGridViewControlCollection.cs
- ReferencedAssembly.cs
- ToolStripDesignerAvailabilityAttribute.cs
- ExternalFile.cs
- OleDbParameterCollection.cs
- EncryptedPackage.cs
- DependencyPropertyHelper.cs
- MemoryMappedViewAccessor.cs
- PolyBezierSegmentFigureLogic.cs
- MessageHeaderException.cs
- EncoderReplacementFallback.cs
- DataControlFieldHeaderCell.cs
- PagedDataSource.cs
- FontInfo.cs
- listitem.cs
- PeerToPeerException.cs
- HttpHandlerAction.cs
- WorkflowCompensationBehavior.cs
- QuotedPrintableStream.cs
- SystemNetHelpers.cs
- FontFaceLayoutInfo.cs
- PerformanceCounterCategory.cs
- Animatable.cs
- TextSimpleMarkerProperties.cs
- FontNamesConverter.cs
- HybridObjectCache.cs
- PropertyConverter.cs
- InfoCardRSAPKCS1KeyExchangeFormatter.cs
- GridPatternIdentifiers.cs
- BadImageFormatException.cs
- wmiprovider.cs
- XmlArrayItemAttribute.cs
- TrackingStringDictionary.cs
- MatrixTransform.cs
- FilterableAttribute.cs
- IntMinMaxAggregationOperator.cs
- ImageBrush.cs
- TextureBrush.cs
- EndOfStreamException.cs
- ButtonBase.cs
- ComplexBindingPropertiesAttribute.cs
- UnmanagedHandle.cs
- Metafile.cs
- DictionarySectionHandler.cs
- ReadOnlyObservableCollection.cs
- CellParaClient.cs
- ToolStripRendererSwitcher.cs
- DescendentsWalker.cs
- MissingMemberException.cs
- CustomAttribute.cs
- SqlConnectionFactory.cs
- DeploymentExceptionMapper.cs
- ManagementOptions.cs
- ActiveDocumentEvent.cs
- CollectionBase.cs
- EmbossBitmapEffect.cs
- ListItemParagraph.cs
- FileFormatException.cs
- Trigger.cs
- Pens.cs
- StylusCollection.cs
- MembershipAdapter.cs
- ProgressBarRenderer.cs
- AdornerLayer.cs
- TypeListConverter.cs
- _ListenerRequestStream.cs
- DrawingImage.cs
- DocumentViewerBaseAutomationPeer.cs
- ScrollViewerAutomationPeer.cs
- QilFactory.cs
- XsltSettings.cs
- RsaSecurityToken.cs
- FlowDocumentView.cs
- DetailsViewRowCollection.cs
- HandlerFactoryCache.cs
- TrackingMemoryStreamFactory.cs
- TextBlockAutomationPeer.cs
- ILGenerator.cs
- EntityDataSource.cs
- Positioning.cs
- ReferentialConstraint.cs