From e6c6fb68b92b1b0ca136eed1da2dd62069a38cb5 Mon Sep 17 00:00:00 2001 From: jbtule Date: Thu, 6 Jun 2013 21:16:08 -0500 Subject: [PATCH] Performance and More Targets, Docs - Improved Tuple Performance (2-5x faster the FSharp.Reflection) - Improved Invocation Performance (minor) - Added LateType(Assembly,String) - One Project Two DLL targets and Testing --- Dynamitey/CacheableInvocation.cs | 23 ++- Dynamitey/Dynamic.cs | 9 +- Dynamitey/DynamicObjects/BaseDictionary.cs | 7 +- Dynamitey/DynamicObjects/BaseForwarder.cs | 57 ++++++- Dynamitey/DynamicObjects/BaseObject.cs | 21 ++- Dynamitey/DynamicObjects/Builder.cs | 62 +++++++- Dynamitey/DynamicObjects/Dictionary.cs | 65 ++++---- Dynamitey/DynamicObjects/Dummy.cs | 7 + .../ExtensionToInstanceProxy.cs | 148 ++++++++++++++---- Dynamitey/DynamicObjects/FauxType.cs | 98 +++++++++++- .../DynamicObjects/FluentStringLookup.cs | 15 +- Dynamitey/DynamicObjects/LateType.cs | 40 ++++- Dynamitey/DynamicObjects/Lazy.cs | 12 +- Dynamitey/DynamicObjects/LinqInstanceProxy.cs | 36 ++++- Dynamitey/DynamicObjects/List.cs | 105 ++++++++----- Dynamitey/DynamicObjects/Recorder.cs | 15 +- Dynamitey/DynamicObjects/RegexMatch.cs | 53 ++++++- Dynamitey/Dynamitey.csproj | 9 +- Dynamitey/Dynamitey.nuspec | 1 + Dynamitey/FluentRegex.cs | 32 +++- Dynamitey/Internal/Curry.cs | 6 + Dynamitey/Internal/InvokeSetters.cs | 2 +- Dynamitey/Internal/Optimization/BinderHash.cs | 2 +- .../Internal/Optimization/InvokeHelper.cs | 1 - .../Internal/Optimization/InvokeHelper.tt | 1 - Dynamitey/Invocation.cs | 13 ++ Dynamitey/InvokeContext.cs | 2 +- Dynamitey/InvokeMemberName.cs | 5 + Dynamitey/PartialApply.cs | 14 +- Dynamitey/Properties/AssemblyInfo.cs | 2 +- Tests/DynamicObjects.cs | 104 +++++++----- Tests/SpeedTest.cs | 1 - Tests/TimeIt.cs | 3 +- dist/build.proj | 7 +- dist/create-nuget.ps1 | 30 +++- 35 files changed, 814 insertions(+), 194 deletions(-) diff --git a/Dynamitey/CacheableInvocation.cs b/Dynamitey/CacheableInvocation.cs index ad7b99d..806727a 100644 --- a/Dynamitey/CacheableInvocation.cs +++ b/Dynamitey/CacheableInvocation.cs @@ -175,6 +175,13 @@ public bool Equals(CacheableInvocation other) && Equals(other._convertType, _convertType); } + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; @@ -182,6 +189,12 @@ public override bool Equals(object obj) return Equals(obj as CacheableInvocation); } + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// public override int GetHashCode() { unchecked @@ -196,8 +209,16 @@ public override int GetHashCode() return result; } } - + + /// + /// Invokes the invocation on specified target with specific args. + /// + /// The target. + /// The args. + /// + /// CacheableInvocation can't change conversion type on invoke.;args + /// Unknown Invocation Kind: public override object Invoke(object target, params object[] args) { var tIContext = target as InvokeContext; diff --git a/Dynamitey/Dynamic.cs b/Dynamitey/Dynamic.cs index 8d1c8e5..6c9601a 100644 --- a/Dynamitey/Dynamic.cs +++ b/Dynamitey/Dynamic.cs @@ -123,6 +123,11 @@ public static CallSite CreateCallSite(CallSiteBinder binder, String_OR_Inv } + /// + /// Puts a dynamic linq proxy around the specified enumerable. + /// + /// The enumerable. + /// public static dynamic Linq(object enumerable) { if(enumerable.GetType().GetInterfaces().Where(it=>it.IsGenericType) @@ -782,10 +787,10 @@ internal static readonly dynamic Impromptu = new DynamicObjects.LateType("ImpromptuInterface.Impromptu, ImpromptuInterface, PublicKeyToken=0b1781c923b2975b"); internal static readonly dynamic TypeDescriptor - = new DynamicObjects.LateType("System.ComponentModel.TypeDescriptor, System, PublicKeyToken=b77a5c561934e089"); + = new DynamicObjects.LateType("System.ComponentModel.TypeDescriptor, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); internal static readonly Type TypeConverterAttributeSL - = Type.GetType("System.ComponentModel.TypeConverter, System, PublicKeyToken=7cec85d7bea7798e", false); + = Type.GetType("System.ComponentModel.TypeConverter, System, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", false); /// /// Goes the extra mile to convert target to type. diff --git a/Dynamitey/DynamicObjects/BaseDictionary.cs b/Dynamitey/DynamicObjects/BaseDictionary.cs index 2ff1afe..2b8cc1c 100644 --- a/Dynamitey/DynamicObjects/BaseDictionary.cs +++ b/Dynamitey/DynamicObjects/BaseDictionary.cs @@ -276,8 +276,13 @@ public bool TryGetValue(string key, out object value) return _dictionary.TryGetValue(key, out value); } - + + /// + /// Sets the property. + /// + /// The key. + /// The value. protected void SetProperty(string key, object value) { object tOldValue; diff --git a/Dynamitey/DynamicObjects/BaseForwarder.cs b/Dynamitey/DynamicObjects/BaseForwarder.cs index 427dc18..30f7194 100644 --- a/Dynamitey/DynamicObjects/BaseForwarder.cs +++ b/Dynamitey/DynamicObjects/BaseForwarder.cs @@ -27,6 +27,9 @@ namespace Dynamitey.DynamicObjects { + /// + /// An proxy object + /// public interface IForwarder { /// @@ -46,7 +49,10 @@ public interface IForwarder public abstract class BaseForwarder : BaseObject, IForwarder { - + + /// + /// Marks whether we are adding or removing the delegate + /// public class AddRemoveMarker { /// @@ -174,16 +180,17 @@ public override bool TryGetMember(GetMemberBinder binder, out object result) return true; } - +#pragma warning disable 1734 /// - /// Provides the implementation for operations that invoke an object. Classes derived from the class can override this method to specify dynamic behavior for operations such as invoking an object or a delegate. + /// Provides the implementation for operations that invoke an object. Classes derived from the class can override this method to specify dynamic behavior for operations such as invoking an object or a delegate. /// /// Provides information about the invoke operation. - /// The arguments that are passed to the object during the invoke operation. For example, for the sampleObject(100) operation, where sampleObject is derived from the class, is equal to 100. + /// The arguments that are passed to the object during the invoke operation. For example, for the sampleObject(100) operation, where sampleObject is derived from the class, is equal to 100. /// The result of the object invocation. /// /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown. /// +#pragma warning restore 1734 public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { if (CallTarget == null) @@ -215,6 +222,13 @@ public override bool TryInvoke(InvokeBinder binder, object[] args, out object re return true; } + /// + /// Tries the invoke member. + /// + /// The binder. + /// The args. + /// The result. + /// public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { if (CallTarget == null) @@ -246,8 +260,14 @@ public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, o return true; } - + + /// + /// Tries the set member. + /// + /// The binder. + /// The value. + /// public override bool TrySetMember(SetMemberBinder binder, object value) { if (CallTarget == null) @@ -283,6 +303,13 @@ public override bool TrySetMember(SetMemberBinder binder, object value) } } + /// + /// Tries the index of the get. + /// + /// The binder. + /// The indexes. + /// The result. + /// public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { if (CallTarget == null) @@ -305,6 +332,13 @@ public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out ob } } + /// + /// Tries the index of the set. + /// + /// The binder. + /// The indexes. + /// The value. + /// public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) { if (CallTarget == null) @@ -340,6 +374,13 @@ public bool Equals(BaseForwarder other) return Equals(other.CallTarget, CallTarget); } + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return ReferenceEquals(null, CallTarget); @@ -348,6 +389,12 @@ public override bool Equals(object obj) return Equals((BaseForwarder) obj); } + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// public override int GetHashCode() { return (CallTarget != null ? CallTarget.GetHashCode() : 0); diff --git a/Dynamitey/DynamicObjects/BaseObject.cs b/Dynamitey/DynamicObjects/BaseObject.cs index 7416264..38ed0bf 100644 --- a/Dynamitey/DynamicObjects/BaseObject.cs +++ b/Dynamitey/DynamicObjects/BaseObject.cs @@ -23,17 +23,26 @@ using System.Reflection; namespace Dynamitey.DynamicObjects { + /// - /// Dynamic Object that knows about the Impromtu Interface return types; - /// Override Typical Dynamic Object methods, and use TypeForName to get the return type of an interface member. + /// Can Represent an equivalent static type to help dynamically convert member output /// - public interface IEquivalentType { + /// + /// Gets or sets the type of the equivalent. + /// + /// + /// The type of the equivalent. + /// FauxType EquivalentType { get; set; } } + /// + /// Dynamic Object that knows about the Impromtu Interface return types; + /// Override Typical Dynamic Object methods, and use TypeForName to get the return type of an interface member. + /// public abstract class BaseObject : DynamicObject, IEquivalentType, IServiceProvider { @@ -47,6 +56,12 @@ protected BaseObject() + /// + /// Tries the name of the member to see if it has a type. + /// + /// Name of the binder. + /// The type. + /// public bool TryTypeForName(string binderName, out Type type) { var eqType = (IEquivalentType) this; diff --git a/Dynamitey/DynamicObjects/Builder.cs b/Dynamitey/DynamicObjects/Builder.cs index 3a981cd..10ed42d 100644 --- a/Dynamitey/DynamicObjects/Builder.cs +++ b/Dynamitey/DynamicObjects/Builder.cs @@ -168,6 +168,11 @@ public dynamic List(params dynamic[] contents) + /// + /// Setup List or Array, takes either one or a list of constructor args that will use objects Type + /// + /// The constructor args. + /// public dynamic ListSetup(params dynamic[] constructorArgs) { var tActivate =constructorArgs.OfType().SingleOrDefault(); @@ -191,26 +196,51 @@ public dynamic ListSetup(params dynamic[] constructorArgs) return this; } + /// + /// Setup List or Array if list has a default constrcutor + /// + /// + /// public dynamic ListSetup() { return ListSetup(new Activate()); } + /// + /// Setup List or Array, takes either one or a list of constructor args that will use objects Type + /// + /// The constructor args factory. + /// public dynamic ListSetup(Func constructorArgsFactory) { return ListSetup((object)constructorArgsFactory); } + /// + /// Setup List or Array if list has a default constrcutor + /// + /// + /// public dynamic ArraySetup() { return ListSetup(new Activate()); } + /// + /// Alternative name for + /// + /// The constructor args. + /// public dynamic ArraySetup(params dynamic[] constructorArgs) { return ListSetup(constructorArgs); } + /// + /// Alternative name for + /// + /// The constructor args factory. + /// public dynamic ArraySetup(Func constructorArgsFactory) { return ListSetup((object)constructorArgsFactory); @@ -275,6 +305,13 @@ public BuilderTrampoline(Builder builder) _buider = builder; } + /// + /// Tries the invoke. + /// + /// The binder. + /// The args. + /// The result. + /// public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { Activate tBuildType; @@ -300,7 +337,15 @@ public class SetupTrampoline : DynamicObject public SetupTrampoline(Builder builder){ _buider = builder; } - + + /// + /// Tries the invoke. + /// + /// The binder. + /// The args. + /// The result. + /// + /// Requires argument names for every argument public override bool TryInvoke(InvokeBinder binder, dynamic[] args, out object result) { if (binder.CallInfo.ArgumentNames.Count != binder.CallInfo.ArgumentCount) @@ -315,7 +360,13 @@ public override bool TryInvoke(InvokeBinder binder, dynamic[] args, out object r } } - + + /// + /// Tries the set member. + /// + /// The binder. + /// The value. + /// public override bool TrySetMember(SetMemberBinder binder, dynamic value){ if (value != null) { @@ -339,6 +390,13 @@ public override bool TrySetMember(SetMemberBinder binder, dynamic value){ return false; } + /// + /// Tries the invoke member. + /// + /// The binder. + /// The args. + /// The result. + /// public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { Type tType; diff --git a/Dynamitey/DynamicObjects/Dictionary.cs b/Dynamitey/DynamicObjects/Dictionary.cs index 3fd28d3..5978be0 100644 --- a/Dynamitey/DynamicObjects/Dictionary.cs +++ b/Dynamitey/DynamicObjects/Dictionary.cs @@ -28,9 +28,7 @@ namespace Dynamitey.DynamicObjects /// /// Similar to Expando Objects but handles null values when the property is defined with an impromptu interface /// - - - public class Dictionary:BaseDictionary,IDictionary + public class Dictionary:BaseDictionary,IDictionary { /// @@ -49,19 +47,6 @@ public Dictionary(IEnumerable> dict) : base(dict) } -//#if !SILVERLIGHT -// /// -// /// Initializes a new instance of the class. -// /// -// /// The info. -// /// The context. -// protected Dictionary(SerializationInfo info, -// StreamingContext context):base(info,context) -// { - -// } -//#endif - /// /// Gets the count. /// @@ -120,8 +105,7 @@ public object this[string key] /// /// Adds extra synatx to intialize properties to match up with clay /// - - public class ChainableDictionary:Dictionary{ + public class ChainableDictionary:Dictionary{ /// @@ -140,24 +124,33 @@ public ChainableDictionary(IEnumerable> dict) : bas } - public override bool TryInvokeMember (InvokeMemberBinder binder, object[] args, out object result) - { - if(base.TryInvokeMember (binder, args, out result)){ - return true; - } - if(binder.CallInfo.ArgumentCount ==1){ - SetProperty(binder.Name, args.FirstOrDefault()); - result = this; - return true; - } - if (binder.CallInfo.ArgumentCount > 1) - { - SetProperty(binder.Name,new List(args)); - result = this; - return true; - } - - return false; + /// + /// Provides the implementation for operations that invoke a member. Classes derived from the class can override this method to specify dynamic behavior for operations such as calling a method. + /// + /// Provides information about the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the statement sampleObject.SampleMethod(100), where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleMethod". The binder.IgnoreCase property specifies whether the member name is case-sensitive. + /// The arguments that are passed to the object member during the invoke operation. For example, for the statement sampleObject.SampleMethod(100), where sampleObject is derived from the class, is equal to 100. + /// The result of the member invocation. + /// + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.) + /// + public override bool TryInvokeMember (InvokeMemberBinder binder, object[] args, out object result) + { + if(base.TryInvokeMember (binder, args, out result)){ + return true; } + if(binder.CallInfo.ArgumentCount ==1){ + SetProperty(binder.Name, args.FirstOrDefault()); + result = this; + return true; + } + if (binder.CallInfo.ArgumentCount > 1) + { + SetProperty(binder.Name,new List(args)); + result = this; + return true; + } + + return false; } + } } diff --git a/Dynamitey/DynamicObjects/Dummy.cs b/Dynamitey/DynamicObjects/Dummy.cs index 5c02f5d..96c2cbb 100644 --- a/Dynamitey/DynamicObjects/Dummy.cs +++ b/Dynamitey/DynamicObjects/Dummy.cs @@ -87,6 +87,13 @@ public override bool TryGetIndex(System.Dynamic.GetIndexBinder binder, object[] } + /// + /// Tries the index of the set. + /// + /// The binder. + /// The indexes. + /// The value. + /// public override bool TrySetIndex(System.Dynamic.SetIndexBinder binder, object[] indexes, object value) { return true; diff --git a/Dynamitey/DynamicObjects/ExtensionToInstanceProxy.cs b/Dynamitey/DynamicObjects/ExtensionToInstanceProxy.cs index 0a1b54f..23afa59 100644 --- a/Dynamitey/DynamicObjects/ExtensionToInstanceProxy.cs +++ b/Dynamitey/DynamicObjects/ExtensionToInstanceProxy.cs @@ -11,7 +11,10 @@ namespace Dynamitey.DynamicObjects { - + + /// + /// Proxy that can turn extension methods into instance methods + /// public class ExtensionToInstanceProxy: BaseForwarder { @@ -21,6 +24,12 @@ public class ExtensionToInstanceProxy: BaseForwarder private readonly Type[] _instanceHints; + /// + /// Gets the instance hints. + /// + /// + /// The instance hints. + /// public IEnumerable InstanceHints { get { return _instanceHints/* ?? KnownInterfaces*/; } @@ -28,6 +37,14 @@ public IEnumerable InstanceHints + /// + /// Initializes a new instance of the class. + /// + /// The target. + /// Type of the extended. + /// The static types. + /// The instance hints. + /// Don't Nest ExtensionToInstance Objects public ExtensionToInstanceProxy(dynamic target, Type extendedType, Type[] staticTypes, Type[] instanceHints = null):base((object)target) { _staticTypes = staticTypes; @@ -46,6 +63,14 @@ public ExtensionToInstanceProxy(dynamic target, Type extendedType, Type[] stati } + /// + /// Provides the implementation for operations that get member values. Classes derived from the class can override this method to specify dynamic behavior for operations such as getting a value for a property. + /// + /// Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive. + /// The result of the get operation. For example, if the method is called for a property, you can assign the property value to . + /// + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a run-time exception is thrown.) + /// public override bool TryGetMember(GetMemberBinder binder, out object result) { @@ -59,21 +84,39 @@ public override bool TryGetMember(GetMemberBinder binder, out object result) return true; } + /// + /// Basic Invoker syntax for dynamic generics + /// public class Invoker:BaseObject { - protected string _name; - protected ExtensionToInstanceProxy _parent; - protected IDictionary _overloadTypes; - protected Type[] _genericParams; - protected Type[] _genericMethodParameters; + /// + /// The name + /// + protected string Name; + /// + /// The parent + /// + protected ExtensionToInstanceProxy Parent; + /// + /// The overload types + /// + protected IDictionary OverloadTypes; + /// + /// The generic params + /// + protected Type[] GenericParams; + /// + /// The generic method parameters + /// + protected Type[] GenericMethodParameters; internal Invoker(string name, Type[] genericParameters, Type[] genericMethodParameters, ExtensionToInstanceProxy parent, Type[] overloadTypes = null) { - _name = name; - _parent = parent; - _genericParams = genericParameters; - _genericMethodParameters = genericMethodParameters; - _overloadTypes = new Dictionary(); + Name = name; + Parent = parent; + GenericParams = genericParameters; + GenericMethodParameters = genericMethodParameters; + OverloadTypes = new Dictionary(); if (overloadTypes == null) { @@ -84,31 +127,31 @@ internal Invoker(string name, Type[] genericParameters, Type[] genericMethodPara if (tNewType.IsGenericType) { - tNewType = tNewType.MakeGenericType(_genericParams); + tNewType = tNewType.MakeGenericType(GenericParams); } var members = tNewType.GetMethods(BindingFlags.Instance | BindingFlags.Public).Where( - it => it.Name == _name).ToList(); + it => it.Name == Name).ToList(); foreach (var tMethodInfo in members) { var tParams = tMethodInfo.GetParameters().Select(it => it.ParameterType).ToArray(); - if (_overloadTypes.ContainsKey(tParams.Length)) + if (OverloadTypes.ContainsKey(tParams.Length)) { - _overloadTypes[tParams.Length] = new Type[] {}; + OverloadTypes[tParams.Length] = new Type[] {}; } else { - _overloadTypes[tParams.Length] = tParams.Select(ReplaceGenericTypes).ToArray(); + OverloadTypes[tParams.Length] = tParams.Select(ReplaceGenericTypes).ToArray(); } } - foreach (var tOverloadType in _overloadTypes.ToList()) + foreach (var tOverloadType in OverloadTypes.ToList()) { if (tOverloadType.Value.Length == 0) { - _overloadTypes.Remove(tOverloadType); + OverloadTypes.Remove(tOverloadType); } } @@ -116,7 +159,7 @@ internal Invoker(string name, Type[] genericParameters, Type[] genericMethodPara } else { - _overloadTypes[overloadTypes.Length] = overloadTypes; + OverloadTypes[overloadTypes.Length] = overloadTypes; } } @@ -139,41 +182,64 @@ private Type ReplaceGenericTypes(Type type) return type; } + /// + /// Tries the get member. + /// + /// The binder. + /// The result. + /// public override bool TryGetMember(GetMemberBinder binder, out object result) { if (binder.Name == "Overloads") { - result = new OverloadInvoker(_name, _genericParams,_genericMethodParameters, _parent); + result = new OverloadInvoker(Name, GenericParams,GenericMethodParameters, Parent); return true; } return base.TryGetMember(binder, out result); } - + + /// + /// Tries the invoke. + /// + /// The binder. + /// The args. + /// The result. + /// public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { object[] tArgs = args; - if (_overloadTypes.ContainsKey(args.Length)) + if (OverloadTypes.ContainsKey(args.Length)) { - tArgs = _overloadTypes[args.Length].Zip(args, Tuple.Create) + tArgs = OverloadTypes[args.Length].Zip(args, Tuple.Create) .Select(it => it.Item2 != null ? Dynamic.InvokeConvert(it.Item2, it.Item1, @explicit: true) : null).ToArray(); } - var name = InvokeMemberName.Create(_name, _genericMethodParameters); + var name = InvokeMemberName.Create(Name, GenericMethodParameters); - result = _parent.InvokeStaticMethod(name, tArgs); + result = Parent.InvokeStaticMethod(name, tArgs); return true; } + /// + /// Tries the index of the get. + /// + /// The binder. + /// The indexes. + /// The result. + /// public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { - result = new Invoker(_name, _genericParams, indexes.Select(it => Dynamic.InvokeConvert(it, typeof(Type), @explicit: true)).Cast().ToArray(), _parent); + result = new Invoker(Name, GenericParams, indexes.Select(it => Dynamic.InvokeConvert(it, typeof(Type), @explicit: true)).Cast().ToArray(), Parent); return true; } } + /// + /// Overload Invoker + /// public class OverloadInvoker:Invoker { internal OverloadInvoker(string name, Type[] genericParameters, Type[] genericMethodParameters, ExtensionToInstanceProxy parent) @@ -182,14 +248,28 @@ internal OverloadInvoker(string name, Type[] genericParameters, Type[] genericMe } + /// + /// Tries the index of the get. + /// + /// The binder. + /// The indexes. + /// The result. + /// public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { - result = new Invoker(_name, _genericParams, _genericMethodParameters, _parent, indexes.Select(it => Dynamic.InvokeConvert(it, typeof(Type), @explicit: true)).Cast().ToArray()); + result = new Invoker(Name, GenericParams, GenericMethodParameters, Parent, indexes.Select(it => Dynamic.InvokeConvert(it, typeof(Type), @explicit: true)).Cast().ToArray()); return true; } } + /// + /// Tries the invoke member. + /// + /// The binder. + /// The args. + /// The result. + /// public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, object[] args, out object result) { if (!base.TryInvokeMember(binder, args, out result)) @@ -218,6 +298,12 @@ public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, o return true; } + /// + /// Invokes the static method. + /// + /// The name. + /// The args. + /// protected object InvokeStaticMethod(String_OR_InvokeMemberName name, object[] args) { var staticType = InvokeContext.CreateStatic; @@ -299,6 +385,14 @@ protected object InvokeStaticMethod(String_OR_InvokeMemberName name, object[] ar return result; } + /// + /// Creates the self. + /// + /// The target. + /// Type of the extended. + /// The static types. + /// The instance hints. + /// protected virtual ExtensionToInstanceProxy CreateSelf(object target, Type extendedType, Type[] staticTypes, Type[] instanceHints) { return new ExtensionToInstanceProxy(target,extendedType,staticTypes, instanceHints); diff --git a/Dynamitey/DynamicObjects/FauxType.cs b/Dynamitey/DynamicObjects/FauxType.cs index accdb62..21a3562 100644 --- a/Dynamitey/DynamicObjects/FauxType.cs +++ b/Dynamitey/DynamicObjects/FauxType.cs @@ -7,19 +7,43 @@ namespace Dynamitey.DynamicObjects { - + + /// + /// A Fake Type + /// public abstract class FauxType { + /// + /// Fauxes the type. + /// + /// The type. + /// public static implicit operator FauxType(Type type) { return new RealType(type); } + /// + /// Gets the members. + /// + /// Name of the binder. + /// public abstract IEnumerable GetMember(string binderName); + /// + /// Gets the contained types. + /// + /// public abstract Type[] GetContainedTypes(); + /// + /// Determines whether the specified type contains the type. + /// + /// The type. + /// + /// true if the specified type contains type; otherwise, false. + /// public virtual bool ContainsType(Type type) { return GetContainedTypes().Contains(type); @@ -27,32 +51,61 @@ public virtual bool ContainsType(Type type) } - + + /// + /// A Fake Type that represents a real type + /// public class RealType : FauxType { + /// + /// RealType implicitly conversts to an actualy Type + /// + /// The type. + /// public static implicit operator Type(RealType type) { return type.TargetType; } + /// + /// An actual Type implicitly conversts to a real type + /// + /// The type. + /// public static implicit operator RealType(Type type) { return new RealType(type); } - + + /// + /// The target type + /// protected readonly Type TargetType; + /// + /// Initializes a new instance of the class. + /// + /// The type. public RealType(Type type) { TargetType = type; } + /// + /// Gets the members. + /// + /// Name of the binder. + /// public override IEnumerable GetMember(string binderName) { return TargetType.GetMember(binderName); } + /// + /// Gets the contained types. + /// + /// public override Type[] GetContainedTypes() { return new[] { TargetType }; @@ -60,11 +113,19 @@ public override Type[] GetContainedTypes() } - - + + + /// + /// A Fake Tupe that is an aggregate of other types + /// public class AggreType : FauxType { + /// + /// Makes the type appendable. + /// + /// The type. + /// public static AggreType MakeTypeAppendable(IEquivalentType type) { if (type.EquivalentType == null) @@ -80,24 +141,40 @@ public static AggreType MakeTypeAppendable(IEquivalentType type) - protected readonly List Types = new List(); + private readonly List Types = new List(); + /// + /// Initializes a new instance of the class. + /// + /// The types. public AggreType(params FauxType[] types) { Types.AddRange(types); } + /// + /// Gets the interface types. + /// + /// public Type[] GetInterfaceTypes() { return Types.SelectMany(it => it.GetContainedTypes()).Where(it => it.IsInterface).ToArray(); } + /// + /// Adds the type. + /// + /// The type. public void AddType(Type type) { if (!ContainsType(type)) Types.Add(type); } + /// + /// Adds the type. + /// + /// The type. public void AddType(FauxType type) { if (type is RealType) @@ -120,6 +197,11 @@ public void AddType(FauxType type) } + /// + /// Gets the members. + /// + /// Name of the binder. + /// public override IEnumerable GetMember(string binderName) { var list = new List(); @@ -130,6 +212,10 @@ public override IEnumerable GetMember(string binderName) return list; } + /// + /// Gets the contained types. + /// + /// public override Type[] GetContainedTypes() { return Types.SelectMany(it => it.GetContainedTypes()).ToArray(); diff --git a/Dynamitey/DynamicObjects/FluentStringLookup.cs b/Dynamitey/DynamicObjects/FluentStringLookup.cs index bf216ea..60c2eb9 100644 --- a/Dynamitey/DynamicObjects/FluentStringLookup.cs +++ b/Dynamitey/DynamicObjects/FluentStringLookup.cs @@ -13,7 +13,6 @@ namespace Dynamitey.DynamicObjects /// /// Building block to use Method calls as dynamic lookups /// - public class FluentStringLookup:DynamicObject { @@ -28,12 +27,26 @@ public FluentStringLookup(Func lookup) _lookup = lookup; } + /// + /// Tries the invoke member. + /// + /// The binder. + /// The args. + /// The result. + /// public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { result = _lookup(binder.Name); return true; } + /// + /// Tries the invoke. + /// + /// The binder. + /// The args. + /// The result. + /// public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { result = null; diff --git a/Dynamitey/DynamicObjects/LateType.cs b/Dynamitey/DynamicObjects/LateType.cs index 6b0b655..cc2f812 100644 --- a/Dynamitey/DynamicObjects/LateType.cs +++ b/Dynamitey/DynamicObjects/LateType.cs @@ -16,15 +16,27 @@ namespace Dynamitey.DynamicObjects public class LateType:BaseForwarder { - + + /// + /// Exception When The Late Type can not be found to bind. + /// public class MissingTypeException:Exception { + /// + /// Initializes a new instance of the class. + /// + /// The typename. public MissingTypeException(string typename) : base(String.Format("Could Not Find Type. {0}", typename)) { } + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner exception. public MissingTypeException(string message, Exception innerException) : base(message, innerException) { @@ -54,6 +66,18 @@ public LateType(string typeName) } + /// + /// Initializes a new instance of the class. + /// + /// The assembly. + /// Name of the type. + public LateType(Assembly assembly, string typeName) + : base(assembly.GetType(typeName, false)) + { + TypeName = typeName; + + } + /// /// Returns a late bound constructor /// @@ -73,6 +97,13 @@ internal ConstructorForward(Type type) { _type = type; } + /// + /// Tries the invoke. + /// + /// The binder. + /// The args. + /// The result. + /// public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { result = Dynamic.InvokeConstructor(_type, Util.NameArgsIfNecessary(binder.CallInfo, args)); @@ -93,6 +124,13 @@ public bool IsAvailable } + /// + /// Gets the call target. + /// + /// + /// The call target. + /// + /// protected override object CallTarget { get diff --git a/Dynamitey/DynamicObjects/Lazy.cs b/Dynamitey/DynamicObjects/Lazy.cs index d36a01a..b0c7a60 100644 --- a/Dynamitey/DynamicObjects/Lazy.cs +++ b/Dynamitey/DynamicObjects/Lazy.cs @@ -14,17 +14,17 @@ namespace Dynamitey.DynamicObjects public abstract class Lazy:BaseForwarder { /// - /// Creates ImpromptuLazy based on the specified valuefactory. + /// Creates Lazy based on the specified valuefactory. /// /// - /// The valuefactory. + /// The value factory. /// public static dynamic Create(Func valueFactory) { return new Lazy(valueFactory); } /// - /// Creates ImpromptuLazy based on the specified target. + /// Creates Lazy based on the specified target. /// /// /// The target. @@ -82,6 +82,12 @@ public override IEnumerable GetDynamicMemberNames() : Enumerable.Empty(); } + /// + /// Gets the call target. + /// + /// + /// The call target. + /// protected override object CallTarget { get diff --git a/Dynamitey/DynamicObjects/LinqInstanceProxy.cs b/Dynamitey/DynamicObjects/LinqInstanceProxy.cs index 7e17fde..cb9fa5a 100644 --- a/Dynamitey/DynamicObjects/LinqInstanceProxy.cs +++ b/Dynamitey/DynamicObjects/LinqInstanceProxy.cs @@ -7,24 +7,43 @@ namespace Dynamitey.DynamicObjects -{ - - +{ + + + /// + /// Extension to Intance Proxy Configured for LINQ IEnumerable methods + /// public class LinqInstanceProxy : ExtensionToInstanceProxy, IEnumerable - { - + { + + /// + /// Initializes a new instance of the class. + /// + /// The target. public LinqInstanceProxy(dynamic target) :base((object)target, typeof(IEnumerable<>), new[]{typeof(Enumerable)}, new[]{typeof(ILinq<>), typeof(IOrderedLinq<>)}) { } + /// + /// Creates the self. + /// + /// The target. + /// Type of the extended. + /// The static types. + /// The instance hints. + /// protected override ExtensionToInstanceProxy CreateSelf(object target, Type extendedType, Type[] staticTypes, Type[] instanceHints) { return new LinqInstanceProxy(target); } - + + /// + /// Gets the enumerator. + /// + /// public IEnumerator GetEnumerator() { return ((dynamic) CallTarget).GetEnumerator(); @@ -36,6 +55,8 @@ IEnumerator IEnumerable.GetEnumerator() } } +#pragma warning disable 1591 +// ReSharper disable UnusedMember.Global public interface ILinq : IEnumerable { TSource Aggregate(Func func); @@ -175,6 +196,7 @@ public interface IOrderedLinq : ILinq, IOrderedEnumerable ThenByDescending(Func keySelector); IOrderedLinq ThenByDescending(Func keySelector, IComparer comparer); } - +// ReSharper restore UnusedMember.Global +#pragma warning restore 1591 } diff --git a/Dynamitey/DynamicObjects/List.cs b/Dynamitey/DynamicObjects/List.cs index f834bbe..a9ab5fb 100644 --- a/Dynamitey/DynamicObjects/List.cs +++ b/Dynamitey/DynamicObjects/List.cs @@ -152,6 +152,11 @@ public int IndexOf(dynamic item) } } + /// + /// Inserts the specified index. + /// + /// The index. + /// The item. public void Insert(int index, dynamic item) { InsertHelper(item,index); @@ -175,11 +180,20 @@ private void InsertHelper(object item, int? index = null) OnCollectionChanged(NotifyCollectionChangedAction.Add, newItem: item, newIndex: index); } + /// + /// Removes at. + /// + /// The index. public void RemoveAt(int index) { RemoveHelper(index: index); } + /// + /// Removes the specified item. + /// + /// The item. + /// public bool Remove(dynamic item) { return RemoveHelper(item); @@ -205,6 +219,14 @@ private bool RemoveHelper(object item = null, int? index = null) return true; } + /// + /// Gets or sets the at the specified index. + /// + /// + /// The . + /// + /// The index. + /// public dynamic this[int index] { get { return _list[index]; } @@ -227,6 +249,14 @@ IEnumerator IEnumerable.GetEnumerator() } + /// + /// Called when [collection changed]. + /// + /// The action. + /// The old item. + /// The new item. + /// The old index. + /// The new index. protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem = null, object newItem = null, int? oldIndex = null, int? newIndex = null) { @@ -292,6 +322,13 @@ public bool Equals(List other) return base.Equals(other) && Equals(other._list, _list); } + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; @@ -299,6 +336,12 @@ public override bool Equals(object obj) return Equals(obj as List); } + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// public override int GetHashCode() { unchecked @@ -326,57 +369,39 @@ protected virtual dynamic GetRepresentedItem() return tItem; } - - -#region Implementation of ITypedList - -//#if !SILVERLIGHT - -// /// -// /// Returns the name of the list. -// /// -// /// An array of objects, for which the list name is returned. This can be null. -// /// The name of the list. -// public string GetListName(PropertyDescriptor[] listAccessors) -// { -// return null; -// } - - -// public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors) -// { -// IEnumerable tList = new string[] { }; -// if (OverrideGettingItemMethodNames != null) -// { -// tList = OverrideGettingItemMethodNames(this); -// } -// else -// { - -// tList = Impromptu.GetMemberNames(GetRepresentedItem(), dynamicOnly: true); -// } - -// return new PropertyDescriptorCollection(tList.Select(it => new ImpromptuPropertyDescriptor(it)).ToArray()); -// } - -//#endif - -#endregion - #region Implementation of ICollection + /// + /// Copies to. + /// + /// The array. + /// The index. public void CopyTo(Array array, int index) { ((IList)_list).CopyTo(array, index); } private readonly object _syncRoot = new object(); + + + /// + /// Gets the sync root. + /// + /// + /// The sync root. + /// public object SyncRoot { get { return _syncRoot; } } + /// + /// Gets a value indicating whether this instance is synchronized. + /// + /// + /// true if this instance is synchronized; otherwise, false. + /// public bool IsSynchronized { get { return false; } @@ -398,6 +423,12 @@ void IList.Remove(object value) Remove(value); } + /// + /// Gets a value indicating whether this instance is fixed size. + /// + /// + /// true if this instance is fixed size; otherwise, false. + /// public bool IsFixedSize { get { return false; } diff --git a/Dynamitey/DynamicObjects/Recorder.cs b/Dynamitey/DynamicObjects/Recorder.cs index 19d7b7b..ed2f562 100644 --- a/Dynamitey/DynamicObjects/Recorder.cs +++ b/Dynamitey/DynamicObjects/Recorder.cs @@ -28,7 +28,6 @@ namespace Dynamitey.DynamicObjects /// /// Proxy that Records Dynamic Invocations on an object /// - public class Recorder:BaseForwarder { @@ -70,6 +69,14 @@ public T ReplayOn(T target) return target; } + /// + /// Provides the implementation for operations that get member values. Classes derived from the class can override this method to specify dynamic behavior for operations such as getting a value for a property. + /// + /// Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive. + /// The result of the get operation. For example, if the method is called for a property, you can assign the property value to . + /// + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a run-time exception is thrown.) + /// public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result) { if (base.TryGetMember(binder, out result)) @@ -80,6 +87,12 @@ public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out obj return false; } + /// + /// Tries the set member. + /// + /// The binder. + /// The value. + /// public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value) { if (base.TrySetMember(binder, value)) diff --git a/Dynamitey/DynamicObjects/RegexMatch.cs b/Dynamitey/DynamicObjects/RegexMatch.cs index 5e720a0..29d0a9a 100644 --- a/Dynamitey/DynamicObjects/RegexMatch.cs +++ b/Dynamitey/DynamicObjects/RegexMatch.cs @@ -8,13 +8,25 @@ namespace Dynamitey.DynamicObjects { + /// + /// A Regex Match Interface + /// public interface IRegexMatch { + /// + /// Gets the value. + /// + /// + /// The value. + /// string Value { get;} } - - + + + /// + /// A Dynamic Regex Match + /// public class RegexMatch : BaseObject, IRegexMatch { @@ -22,6 +34,11 @@ public class RegexMatch : BaseObject, IRegexMatch private readonly Regex _regex; + /// + /// Initializes a new instance of the class. + /// + /// The match. + /// The regex. public RegexMatch(Match match, Regex regex = null) { _match = match; @@ -29,6 +46,10 @@ public RegexMatch(Match match, Regex regex = null) } + /// + /// Gets the dynamic member names. + /// + /// public override IEnumerable GetDynamicMemberNames() { if (_regex == null) @@ -36,6 +57,12 @@ public override IEnumerable GetDynamicMemberNames() return _regex.GetGroupNames(); } + /// + /// Tries the get member. + /// + /// The binder. + /// The result. + /// public override bool TryGetMember(GetMemberBinder binder, out object result) { var tGroup = _match.Groups[binder.Name]; @@ -55,6 +82,14 @@ public override bool TryGetMember(GetMemberBinder binder, out object result) return true; } + /// + /// Gets the with the specified value. + /// + /// + /// The . + /// + /// The value. + /// public string this[int value] { get @@ -69,6 +104,14 @@ public string this[int value] } } + /// + /// Gets the with the specified value. + /// + /// + /// The . + /// + /// The value. + /// public string this[string value] { get @@ -88,6 +131,12 @@ string IRegexMatch.Value get { return _match.Value; } } + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// public override string ToString() { return _match.ToString(); diff --git a/Dynamitey/Dynamitey.csproj b/Dynamitey/Dynamitey.csproj index 512f9d9..a31a13d 100644 --- a/Dynamitey/Dynamitey.csproj +++ b/Dynamitey/Dynamitey.csproj @@ -13,7 +13,7 @@ v4.0 false true - Profile154 + Profile154 512 {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} @@ -33,6 +33,10 @@ TRACE prompt 4 + bin\Release\Dynamitey.XML + + + bin\Release.net40\Dynamitey.XML true @@ -112,10 +116,9 @@ - + -