< Summary

Information
Class: ImpromptuInterface.Build.ActLikeProxy
Assembly: ImpromptuInterface
File(s): /home/runner/work/impromptu-interface/impromptu-interface/ImpromptuInterface/src/EmitProxy/ActLikeProxy.cs
Line coverage
51%
Covered lines: 27
Uncovered lines: 25
Coverable lines: 52
Total lines: 233
Line coverage: 51.9%
Branch coverage
73%
Covered branches: 41
Total branches: 56
Branch coverage: 73.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ImpromptuInterface.IActLikeProxy.get_Original()100%11100%
ImpromptuInterface.IActLikeProxy.get_Maker()100%11100%
ImpromptuInterface.Build.IActLikeProxyInitialize.Initialize(...)71.42%181473.68%
Equals(...)93.75%1616100%
Equals(...)80%1010100%
GetHashCode()100%44100%
GetObjectData(...)0%7280%
ToString()100%44100%

File(s)

/home/runner/work/impromptu-interface/impromptu-interface/ImpromptuInterface/src/EmitProxy/ActLikeProxy.cs

#LineLine coverage
 1//
 2//  Copyright 2010  Ekon Benefits
 3//
 4//    Licensed under the Apache License, Version 2.0 (the "License");
 5//    you may not use this file except in compliance with the License.
 6//    You may obtain a copy of the License at
 7//
 8//        http://www.apache.org/licenses/LICENSE-2.0
 9//
 10//    Unless required by applicable law or agreed to in writing, software
 11//    distributed under the License is distributed on an "AS IS" BASIS,
 12//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13//    See the License for the specific language governing permissions and
 14//    limitations under the License.
 15
 16using System;
 17using System.Collections.Generic;
 18using System.Linq;
 19using System.Runtime.Serialization;
 20using Dynamitey.DynamicObjects;
 21using ImpromptuInterface.Optimization;
 22
 23namespace ImpromptuInterface.Build
 24{
 25    /// <summary>
 26    /// This interface can be used to define your own custom proxy if you preload it.
 27    /// </summary>
 28    /// <remarks>
 29    /// Advanced usage only! This is required as well as <see cref="ActLikeProxyAttribute"></see>
 30    /// </remarks>
 31    public interface IActLikeProxyInitialize : IActLikeProxy
 32    {
 33        ///<summary>
 34        /// Method used to Initialize Proxy
 35        ///</summary>
 36        ///<param name="original"></param>
 37        ///<param name="interfaces"></param>
 38        ///<param name="informalInterface"></param>
 39        void Initialize(dynamic original, IEnumerable<Type> interfaces =null, IDictionary<string, Type> informalInterfac
 40    }
 41
 42
 43    /// <summary>
 44    /// Base class of Emited ProxiesC:\Documents and Settings\jayt\My Documents\Visual Studio 2010\Projects\impromptuint
 45    /// </summary>
 46    [Serializable]
 47    public abstract class ActLikeProxy : IActLikeProxyInitialize, ISerializable
 48    {
 49        /// <summary>
 50        /// Returns the proxied object
 51        /// </summary>
 52        /// <value></value>
 53        // Not null until Initialize runs, but a stand-in that answers every operation with an
 54        // explanation. A proxy built by Activator.CreateInstance rather than ActLike otherwise
 55        // fails on first use with "Cannot perform runtime binding on a null reference", which
 56        // names neither the cause nor the cure. A checked getter would work for the emitted
 57        // members, which all read through IActLikeProxy.Original - but Equals, GetHashCode,
 58        // ToString and GetObjectData read this field directly, and the check cost about 10% of
 59        // the time of a forwarded property set, measured. The stand-in covers every reader and
 60        // costs nothing.
 61        private dynamic ActLikeProxyOriginal { get; set; } = NoTarget.Instance;
 62        private ActLikeMaker ActLikeProxyActLikeMaker { get; set; }
 21663        dynamic IActLikeProxy.Original => ActLikeProxyOriginal;
 1264        ActLikeMaker IActLikeProxy.Maker => ActLikeProxyActLikeMaker;
 65        private bool _init = false;
 66
 67        /// <summary>
 68        /// Method used to Initialize Proxy
 69        /// </summary>
 70        /// <param name="original"></param>
 71        /// <param name="interfaces"></param>
 72        /// <param name="informalInterface"></param>
 73        /// <param name="maker"></param>
 74        void IActLikeProxyInitialize.Initialize(dynamic original, IEnumerable<Type> interfaces, IDictionary<string, Type
 75        {
 13076            if(((object)original) == null)
 077                throw new ArgumentNullException(nameof(original), "Can't proxy a Null value");
 78
 79            // Not a hot path, and it is the one way the stand-in could be taken back in as a
 80            // real target - through a hand-built ActLikeProxySerializationHelper, say.
 13081            NoTarget.ThrowIfAbsent((object)original);
 82
 12983            if (_init)
 084                throw new MethodAccessException("Initialize should not be called twice!");
 12985            _init = true;
 12986            ActLikeProxyOriginal = original;
 87
 12988            if (maker == null)
 89            {
 090                maker = BuildProxy.DefaultProxyMaker;
 91            }
 92
 12993            ActLikeProxyActLikeMaker = maker;
 94
 12995            if (ActLikeProxyOriginal is IEquivalentType dynamicObj)
 96            {
 3897                if (interfaces != null)
 98                {
 3899                    var aggreType = AggreType.MakeTypeAppendable(dynamicObj);
 100
 152101                    foreach (var type in interfaces)
 102                    {
 38103                        aggreType.AddType(type);
 104
 105                    }
 106                }
 38107                if (informalInterface != null)
 108                {
 0109                    var aggreType = AggreType.MakeTypeAppendable(dynamicObj);
 0110                    aggreType.AddType(new PropretySpecType(informalInterface));
 111                }
 112            }
 129113        }
 114
 115
 116
 117        /// <summary>
 118        /// Two proxies that have targets are equal when the objects they wrap are. That
 119        /// comparison is symmetric and agrees with <see cref="GetHashCode"/>, so such proxies
 120        /// work as dictionary keys and find each other there.
 121        /// </summary>
 122        /// <remarks>
 123        /// Comparing a proxy against a *raw* object is a convenience on top of that, and only
 124        /// works with the proxy as the receiver: <c>proxy.Equals(target)</c> is <c>true</c>,
 125        /// <c>target.Equals(proxy)</c> is not, because the target is an ordinary object that
 126        /// knows nothing of proxies. A hash lookup asks the stored key, so a dictionary keyed
 127        /// by the target will not find the proxy - key it by the proxy, or unwrap first.
 128        ///
 129        /// A proxy with no target is outside all of this: every member of one throws, including
 130        /// <see cref="GetHashCode"/>, so it cannot be a key at all. Two of them do compare equal
 131        /// to each other, since they share the one stand-in - a quirk of an object that is
 132        /// already an error, not a case to rely on.
 133        /// </remarks>
 134        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
 135        /// <returns>
 136        ///   <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c
 137        /// </returns>
 138        public override bool Equals(object obj)
 139        {
 27140            if (ReferenceEquals(null, obj)) return false;
 25141            if (ReferenceEquals(this, obj)) return true;
 29142            if (ReferenceEquals(ActLikeProxyOriginal, obj)) return true;
 25143            if (!(obj is ActLikeProxy)) return ActLikeProxyOriginal.Equals(obj);
 17144            return Equals((ActLikeProxy) obj);
 145        }
 146
 147        /// <summary>
 148        /// Two proxies that have targets are equal when the objects they wrap are - including
 149        /// two proxies over distinct but equal targets, which compare by the targets' own
 150        /// equality.
 151        /// </summary>
 152        /// <remarks>
 153        /// The interfaces each proxy was built for take no part in this, so two proxies over one
 154        /// target compare equal even when they present different interfaces.
 155        /// </remarks>
 156        /// <param name="other">The other.</param>
 157        /// <returns></returns>
 158        public bool Equals(ActLikeProxy other)
 159        {
 17160            if (ReferenceEquals(null, other)) return false;
 17161            if (ReferenceEquals(this, other)) return true;
 22162            if (ReferenceEquals(ActLikeProxyOriginal, other.ActLikeProxyOriginal)) return true;
 163            // This proxy's target first: object.Equals dispatches on its first argument, and
 164            // asking the *other* one to answer means a healthy proxy compared against a proxy
 165            // with no target fails on the other's behalf rather than answering false.
 12166            return Equals((object)ActLikeProxyOriginal, (object)other.ActLikeProxyOriginal);
 167        }
 168
 169        /// <summary>
 170        /// Returns a hash code for this instance.
 171        /// </summary>
 172        /// <returns>
 173        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
 174        /// </returns>
 175        public override int GetHashCode()
 176        {
 12177            return ActLikeProxyOriginal.GetHashCode();
 178        }
 179
 180#if !SILVERLIGHT
 181
 182        /// <summary>
 183        /// Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"/> with the data needed to serialize
 184        /// </summary>
 185        /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.
 186        /// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext"/>) fo
 187        /// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </ex
 188        public void GetObjectData(SerializationInfo info, StreamingContext context)
 189        {
 0190            info.SetType(typeof(ActLikeProxySerializationHelper));
 191
 0192        var tCustomAttr =
 0193                GetType().GetCustomAttributes(typeof (ActLikeProxyAttribute), false).OfType<ActLikeProxyAttribute>().
 0194                    FirstOrDefault();
 195
 196
 0197            info.AddValue("Context",
 0198                          tCustomAttr == null
 0199                          ? null
 0200                          : tCustomAttr.Context,typeof(Type));
 201
 202
 0203      if(Util.IsMono){
 0204        info.AddValue("MonoInterfaces",
 0205                          tCustomAttr == null
 0206                          ? null
 0207                          : tCustomAttr.Interfaces.Select(it=>it.AssemblyQualifiedName).ToArray(),typeof(string[]));
 208      }else{
 0209              info.AddValue("Interfaces",
 0210                          tCustomAttr == null
 0211                          ? null
 0212                          : tCustomAttr.Interfaces,typeof(Type[]));
 213      }
 214
 215
 0216            NoTarget.ThrowIfAbsent((object)ActLikeProxyOriginal);
 0217            info.AddValue("Original", (object)ActLikeProxyOriginal);
 218
 0219        }
 220#endif
 221
 222        /// <summary>
 223        /// Returns a <see cref="System.String"/> that represents this instance.
 224        /// </summary>
 225        /// <returns>
 226        /// A <see cref="System.String"/> that represents this instance.
 227        /// </returns>
 228        public override string ToString()
 229        {
 2230            return ActLikeProxyOriginal.ToString();
 231        }
 232    }
 233}