/// <inheritdoc cref="IDependencyEmitter" /> public FieldBuilder CreateInterceptorDependency(TypeBuilder type) { Ensures.NotNull(type, nameof(type)); var field = type.DefineField( "_interceptor", typeof(IInterceptor), FieldAttributes.Private | FieldAttributes.InitOnly); return(field); }
/// <inheritdoc cref="IMockBehavior{TMock}" /> public ICallBehavior <TMock> That(Expression <Action <TMock> > mockedCall) { Ensures.NotNull(mockedCall, nameof(mockedCall)); if (mockedCall.Body is MethodCallExpression methodCall) { return(new CallBehavior <TMock>(Arrangements, methodCall.Method, this)); } throw new NotImplementedException(); }
/// <inheritdoc cref="IAssemblyEmitter" /> public ITypeDecoratorEmitter EmitDecoratorType(string typeFullName) { Ensures.NotNull(typeFullName, nameof(typeFullName)); var builder = Module.Value.DefineType( typeFullName, TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class); var emitter = CreateTypeDecoratorEmitter(builder); return(emitter); }
/// <inheritdoc cref="IArrangement" /> public bool CanApplyTo(IInvocation invocation) { Ensures.NotNull(invocation, nameof(invocation)); if (invocation.HasFeature <IReturnValue <T> >()) { return(invocation.Signature == Signature); } return(false); }
/// <inheritdoc cref="IArrangement" /> public bool TryApplyTo(IInvocation invocation) { Ensures.NotNull(invocation, nameof(invocation)); if (invocation.Signature == Signature) { throw ExceptionFactory(); } return(false); }
/// <summary> /// Emits a call to the <see cref="IInterceptor.Intercept(IInvocation)"/> method. /// </summary> /// <param name="body"> The body of the dynamic method or property. </param> /// <param name="interceptorField"> The <see cref="IInterceptor"/> backing field. </param> /// <param name="invocationVariable"> The local <see cref="IInvocation"/> variable. </param> /// <remarks> /// Emits the following source code: /// /// <![CDATA[ /// _interceptor.Intercept(invocation); /// ]]> /// </remarks> public static void EmitInterceptCall( this ILGenerator body, FieldBuilder interceptorField, LocalBuilder invocationVariable) { Ensures.NotNull(interceptorField, nameof(interceptorField)); Ensures.NotNull(invocationVariable, nameof(invocationVariable)); body.Emit(OpCodes.Ldarg_0); body.Emit(OpCodes.Ldfld, interceptorField); body.Emit(OpCodes.Ldloc, invocationVariable.LocalIndex); body.Emit(OpCodes.Callvirt, Intercept.Value); body.Emit(OpCodes.Pop); }
/// <inheritdoc cref="IArrangementCollection" /> public bool TryApplyTo(IInvocation invocation) { Ensures.NotNull(invocation, nameof(invocation)); var wasOneArrangementApplied = false; foreach (var arrangement in Arrangements) { wasOneArrangementApplied |= arrangement.TryApplyTo(invocation); } return(wasOneArrangementApplied); }
/// <inheritdoc cref="IDependencyEmitter" /> public FieldBuilder CreateDecorateeDependency(TypeBuilder type, Type decorateeType) { Ensures.NotNull(type, nameof(type)); Ensures.NotNull(decorateeType, nameof(decorateeType)); var field = type.DefineField( "_decoratee", decorateeType, FieldAttributes.Private | FieldAttributes.InitOnly); return(field); }
/// <summary> /// Emits code to return the <see cref="IReturnValue{T}.ReturnValue"/>. /// </summary> /// <param name="body"> The body of the dynamic method. </param> /// <param name="returnValueFeatureVariable"> The emitted local <see cref="IReturnValue{T}"/> variable. </param> /// <typeparam name="T"> The concrete type of the return value. </typeparam> /// <remarks> /// Emits the following source code: /// <![CDATA[ /// return returnValueFeature.ReturnValue; /// ]]> /// </remarks> public static void EmitReturnStatement <T>( this ILGenerator body, LocalBuilder returnValueFeatureVariable) { Ensures.NotNull(returnValueFeatureVariable, nameof(returnValueFeatureVariable)); body.Emit(OpCodes.Ldloc, returnValueFeatureVariable.LocalIndex); var returnValueSignature = ReturnValueFeaturePropertyCache.GetOrAdd(typeof(T), GetReturnValue <T>()); body.Emit(OpCodes.Callvirt, returnValueSignature); body.Emit(OpCodes.Ret); }
/// <summary> /// Emits code to return the <see cref="IAsyncInvocation{T}.AsyncReturnValue"/>. /// </summary> /// <param name="body"> The body of the dynamic method. </param> /// <param name="asyncFeatureVariable"> The emitted local <see cref="IAsyncInvocation{T}"/> variable. </param> /// <typeparam name="T"> The concrete type of the <see cref="IAsyncInvocation"/> feature. </typeparam> /// <remarks> /// Emits the following source code: /// <![CDATA[ /// return asyncFeature.AsyncReturnValue; /// ]]> /// </remarks> public static void EmitAsyncReturnStatement <T>( this ILGenerator body, LocalBuilder asyncFeatureVariable) where T : IAsyncInvocation { Ensures.NotNull(asyncFeatureVariable, nameof(asyncFeatureVariable)); body.Emit(OpCodes.Ldloc, asyncFeatureVariable.LocalIndex); var asyncReturnValueSignature = AsyncFeatureReturnValueCache.GetOrAdd(typeof(T), GetAsyncFeatureReturnValue <T>()); body.Emit(OpCodes.Callvirt, asyncReturnValueSignature); body.Emit(OpCodes.Ret); }
/// <inheritdoc cref="IDynamicProxyFactory" /> public T CreateDecorator <T>(T decoratee, IInterceptor interceptor) where T : notnull { Ensures.NotNull(interceptor, nameof(interceptor)); var signature = typeof(T); var decorator = CreateDecorator(signature, decoratee, interceptor); if (decorator is T typedDecorator) { return(typedDecorator); } throw new Exception($"Unable to create a decorator for interface {signature.Name}"); }
/// <summary> /// Emits code to create a new <see cref="PropertyInvocation"/> instance for the given feature. /// </summary> /// <param name="body"> The body of the dynamic method. </param> /// <param name="propertySignatureVariable"> The emitted local <see cref="PropertyInfo"/> variable. </param> /// <param name="propertyFeatureVariable"> The emitted local <see cref="PropertyInvocation"/> variable. </param> /// <remarks> /// Emits the following source code: /// <![CDATA[ /// propertyFeature = new PropertyInvocation(propertySignature); /// ]]> /// </remarks> public static void EmitNewPropertyFeature( this ILGenerator body, LocalBuilder propertySignatureVariable, LocalBuilder propertyFeatureVariable) { Ensures.NotNull(propertySignatureVariable, nameof(propertySignatureVariable)); Ensures.NotNull(propertyFeatureVariable, nameof(propertyFeatureVariable)); // propertySignature body.Emit(OpCodes.Ldloc, propertySignatureVariable.LocalIndex); // propertyFeature = new PropertyInvocation(...) body.Emit(OpCodes.Newobj, CreatePropertyInvocation.Value); body.Emit(OpCodes.Stloc, propertyFeatureVariable.LocalIndex); }
/// <inheritdoc cref="IArrangement" /> public bool CanApplyTo(IInvocation invocation) { Ensures.NotNull(invocation, nameof(invocation)); if (invocation.TryGetFeature <IParameterOut>(out var outParameterFeature)) { if (invocation.Signature == Signature) { return(outParameterFeature .OutParameterCollection .Any(p => p.Name == OutParameterName && p.Type == typeof(T))); } } return(false); }
/// <summary> /// Emits a call to the <see cref="IInterceptor.Intercept(IInvocation)"/> method along with an if statement. /// </summary> /// <param name="body"> The body of the dynamic method or property. </param> /// <param name="interceptorField"> The <see cref="IInterceptor"/> backing field. </param> /// <param name="invocationVariable"> The local <see cref="IInvocation"/> variable. </param> /// <param name="elseLabel"> The label that defines the start of the "else" block. </param> /// <remarks> /// Emits the following source code: /// /// <![CDATA[ /// if(_interceptor.Intercept(invocation)) /// ]]> /// </remarks> public static void EmitIfInterceptCall( this ILGenerator body, FieldBuilder interceptorField, LocalBuilder invocationVariable, out Label elseLabel) { Ensures.NotNull(interceptorField, nameof(interceptorField)); Ensures.NotNull(invocationVariable, nameof(invocationVariable)); body.Emit(OpCodes.Ldarg_0); body.Emit(OpCodes.Ldfld, interceptorField); body.Emit(OpCodes.Ldloc, invocationVariable.LocalIndex); body.Emit(OpCodes.Callvirt, Intercept.Value); elseLabel = body.DefineLabel(); body.Emit(OpCodes.Brtrue_S, elseLabel); }
/// <summary> /// Emits code to create a new parameter feature instance for the given feature. /// </summary> /// <typeparam name="T"> /// <see cref="ParameterIn"/>, <see cref="ParameterRef"/> or <see cref="ParameterOut"/>. /// </typeparam> /// <param name="body"> The body of the dynamic method. </param> /// <param name="methodSignatureVariable"> The emitted local <see cref="MethodInfo"/> variable. </param> /// <param name="parameterSignatures"> The dynamic method's parameter signatures. </param> /// <param name="parameterFeatureVariable"> The emitted local parameter variable. </param> /// <remarks> /// Emits the following source code: /// /// <![CDATA[ /// parameterFeature = new ParameterIn/Ref(methodSignature, new[] { parameter1, ... parameterN }); /// ]]> /// /// or /// /// <![CDATA[ /// parameterFeature = new ParameterOut(methodSignature); /// ]]> /// </remarks> public static void EmitNewParameterFeature <T>( this ILGenerator body, LocalBuilder methodSignatureVariable, ParameterInfo[] parameterSignatures, LocalBuilder parameterFeatureVariable) { Ensures.NotNull(methodSignatureVariable, nameof(methodSignatureVariable)); Ensures.NotNull(parameterSignatures, nameof(parameterSignatures)); Ensures.NotNull(parameterFeatureVariable, nameof(parameterFeatureVariable)); // methodSignature body.Emit(OpCodes.Ldloc, methodSignatureVariable.LocalIndex); if (typeof(T) != typeof(ParameterOut)) { // new[] { parameter1, ... parameterN } body.Emit(OpCodes.Ldc_I4, parameterSignatures.Length); body.Emit(OpCodes.Newarr, typeof(object)); for (var i = 0; i < parameterSignatures.Length; ++i) { body.Emit(OpCodes.Dup); body.Emit(OpCodes.Ldc_I4, i); body.Emit(OpCodes.Ldarg, parameterSignatures[i].Position + 1); var type = parameterSignatures[i].ParameterType; if (type.IsByRef) { type = type.GetElementType() ?? throw new MethodInfoException(typeof(Type), nameof(Type.GetElementType)); body.Emit(OpCodes.Ldobj, type); } if (type.IsValueType) { body.Emit(OpCodes.Box, type); } body.Emit(OpCodes.Stelem_Ref); } } // parameterFeature = new ParameterIn/Ref/Out(...) var featureCtor = ParameterFeatureCache.GetOrAdd(typeof(T), _ => InitializeParameterFeature <T>()); body.Emit(OpCodes.Newobj, featureCtor); body.Emit(OpCodes.Stloc, parameterFeatureVariable.LocalIndex); }
/// <inheritdoc cref="IArrangement" /> public bool TryApplyTo(IInvocation invocation) { Ensures.NotNull(invocation, nameof(invocation)); if (invocation.Signature == Signature) { if (invocation.HasFeature <IAsyncInvocation>()) { if (invocation.TryGetFeature <IAsyncInvocation <T> >(out var asyncFeature)) { asyncFeature.AsyncReturnValue = GetNextReturnValue(); return(true); } else if (invocation.TryGetFeature <IAsyncInvocation <Task <T> > >(out var asyncTaskFeature)) { var returnValue = GetNextReturnValue(); asyncTaskFeature.AsyncReturnValue = Task.FromResult(returnValue); return(true); } else if (invocation.TryGetFeature <IAsyncInvocation <ValueTask <T> > >(out var asyncValueTaskFeature)) { var returnValue = GetNextReturnValue(); asyncValueTaskFeature.AsyncReturnValue = new ValueTask <T>(returnValue); return(true); } else if (invocation.TryGetFeature <IAsyncInvocation <IAsyncEnumerable <T> > >(out var asyncEnumerableFeature)) { var returnValue = GetNextReturnValue(); asyncEnumerableFeature.AsyncReturnValue = AsyncEnumerable.Create(_ => AsyncEnumerator.Create( () => new ValueTask <bool>(true), () => returnValue, () => default)); return(true); } } else if (invocation.TryGetFeature <IReturnValue <T> >(out var returnValueFeature)) { returnValueFeature.ReturnValue = GetNextReturnValue(); return(true); } } return(false); }
/// <inheritdoc cref="IMockedDependencyFactory" /> public IMockedDependency CreateMockedDependency(Type dependency, MockBehavior behavior) { Ensures.NotNull(dependency, nameof(dependency)); Ensures.IsInterface(dependency); var arrangements = new ArrangementCollection(); var interceptor = InterceptorFactory.CreateInterceptorFor(behavior, arrangements); var proxy = DynamicProxyFactory.CreateForInterface(dependency, interceptor); var mockedDependencyType = typeof(MockedDependency <>).MakeGenericType(dependency); var instance = Activator.CreateInstance(mockedDependencyType, new[] { arrangements, interceptor, proxy }); if (instance is IMockedDependency mockedDependency) { return(mockedDependency); } throw new InvalidOperationException("Invalid mocked dependency instance"); }
/// <inheritdoc cref="IInterceptor" /> public bool Intercept(IInvocation invocation) { Ensures.NotNull(invocation, nameof(invocation)); if (invocation.TryGetFeature <IPropertySetterValue>(out var setter)) { if (DiscoveredSetter == null) { DiscoveredSetter = setter.Signature.GetSetMethod(); return(true); } else { throw new Exception("Discovered more than one property setter call"); } } return(false); }
/// <inheritdoc cref="IMockBehavior{TMock}" /> public ICallBehavior <TMock, TResult> That <TResult>(Expression <Func <TMock, TResult> > mockedCall) { Ensures.NotNull(mockedCall, nameof(mockedCall)); if (mockedCall.Body is MethodCallExpression methodCall) { return(new CallBehavior <TMock, TResult>(Arrangements, methodCall.Method, this)); } else if (mockedCall.Body is MemberExpression expression) { if (expression.Member is PropertyInfo signature && signature.CanRead) { var getter = signature.GetGetMethod() ?? throw new Exception($"Property {signature.Name} has no getter"); return(new CallBehavior <TMock, TResult>(Arrangements, getter, this)); } } throw new NotImplementedException(); }
/// <inheritdoc cref="IMockBehavior{TMock}" /> public ICallBehavior <TMock> ThatAssigning(Action <TMock> mockedSetterCall) { Ensures.NotNull(mockedSetterCall, nameof(mockedSetterCall)); var interceptor = new PropertySetterInterceptor(); try { var proxy = ProxyFactory.Value.CreateForInterface <TMock>(interceptor); mockedSetterCall(proxy); } catch (Exception e) { throw new Exception("Action is no valid property setter", e); } var setter = interceptor.DiscoveredSetter ?? throw new Exception($"Property has no setter"); return(new CallBehavior <TMock>(Arrangements, setter, this)); }
/// <inheritdoc cref="IInterceptorFactory" /> public IInterceptor CreateInterceptorFor(MockBehavior behavior, IArrangementCollection arrangements) { Ensures.NotNull(arrangements); if (behavior == MockBehavior.Loose) { return(new LooseMockInterceptor(arrangements)); } if (behavior == MockBehavior.Strict) { return(new StrictMockInterceptor(arrangements)); } if (behavior == MockBehavior.Partial) { return(new PartialMockInterceptor(arrangements)); } throw new NotSupportedException(); }
/// <summary> /// Emit a call to <see cref="IParameterRefOrOut.GetValue{T}(string)"/> and store the result in the /// associated ref or out parameter of the intercepted method. /// </summary> /// <typeparam name="T"> /// <see cref="ParameterRef"/> or <see cref="ParameterOut"/>. /// </typeparam> /// <param name="body"> The body of the dynamic method. </param> /// <param name="parameterSignatures"> The signatures of the ref/out parameter to be synced. </param> /// <param name="parameterRefFeatureVariable"> The emitted local parameter ref/out feature variable. </param> /// <remarks> /// Emits the following source code: /// <![CDATA[ /// ref/outParameter1 = parameterRef/OutFeature.GetValue<ParameterType1>("ParameterName1"); /// ... /// ref/outParameterN = parameterRef/OutFeature.GetValue<ParameterTypeN>("ParameterNameN"); /// ]]> /// </remarks> public static void EmitSyncParameter <T>( this ILGenerator body, ParameterInfo[] parameterSignatures, LocalBuilder parameterRefFeatureVariable) { Ensures.NotNull(parameterSignatures, nameof(parameterSignatures)); Ensures.NotNull(parameterRefFeatureVariable, nameof(parameterRefFeatureVariable)); foreach (var parameterSignature in parameterSignatures) { body.Emit(OpCodes.Ldarg, parameterSignature.Position + 1); body.Emit(OpCodes.Ldloc, parameterRefFeatureVariable.LocalIndex); body.Emit(OpCodes.Ldstr, parameterSignature.Name ?? "unknown"); var type = parameterSignature.ParameterType.GetElementType() ?? throw new MethodInfoException(typeof(Type), nameof(Type.GetElementType)); var getValue = ParameterGetValueCache.GetOrAdd(type, _ => InitializeParameterGetValue(type)); body.Emit(OpCodes.Callvirt, getValue); body.Emit(OpCodes.Stobj, type); } }
/// <inheritdoc cref="IArrangement" /> public bool TryApplyTo(IInvocation invocation) { Ensures.NotNull(invocation, nameof(invocation)); if (invocation.Signature == Signature) { if (invocation.TryGetFeature <IParameterOut>(out var outParameterFeature)) { var parameter = outParameterFeature .OutParameterCollection .SingleOrDefault(p => p.Name == OutParameterName && p.Type == typeof(T)); if (parameter != null) { parameter.Value = OutParameterValue; return(true); } } } return(false); }
/// <inheritdoc cref="IDynamicProxyFactory" /> public object CreateForInterface(Type signature, IInterceptor interceptor) { Ensures.NotNull(signature, nameof(signature)); Ensures.NotNull(interceptor, nameof(interceptor)); try { var proxyType = ProxyTypeCache.GetOrAdd(signature, EmitProxyTypeFor); var proxy = Activator.CreateInstance(proxyType, new[] { interceptor }); if (proxy != null) { return(proxy); } } catch (Exception e) { throw new Exception($"Unable to create a proxy for interface {signature.Name}", e); } throw new Exception($"Unable to create a proxy for interface {signature.Name}"); }
/// <inheritdoc cref="IDynamicProxyFactory" /> public object CreateDecorator(Type signature, object decoratee, IInterceptor interceptor) { Ensures.NotNull(signature, nameof(signature)); Ensures.NotNull(decoratee, nameof(decoratee)); Ensures.NotNull(interceptor, nameof(interceptor)); try { var decoratorType = PartialProxyTypeCache.GetOrAdd(signature, EmitPartialProxyTypeFor); var decorator = Activator.CreateInstance(decoratorType, new[] { decoratee, interceptor }); if (decorator != null) { return(decorator); } } catch (Exception e) { throw new Exception($"Unable to create a decorator for interface {signature.Name}", e); } throw new Exception($"Unable to create a decorator for interface {signature.Name}"); }
/// <inheritdoc cref="ITypeEmitter" /> public void ImplementInterface(Type signature) { Ensures.NotNull(signature); Ensures.IsInterface(signature); var interceptorField = Dependencies.CreateInterceptorDependency(Type); Dependencies.CreateConstructor(Type, interceptorField); Type.AddInterfaceImplementation(signature); foreach (var property in signature.GetProperties()) { var emitter = PropertyEmitterFactory.CreatePropertyEmitterFor(property, Type, interceptorField); emitter.EmitPropertyImplementation(); } foreach (var method in signature.GetMethods().Where(m => !m.IsSpecialName)) { var emitter = MethodEmitterFactory.CreateMethodEmitterFor(method, Type, interceptorField); emitter.EmitMethodImplementation(); } }
/// <summary> /// Creates a new instance of the <see cref="ParameterIn"/> type. /// </summary> /// <param name="signature"> The intercepted method's signature. </param> /// <param name="values"> The intercepted method's in(put) parameters. </param> public ParameterIn(MethodInfo signature, object?[] values) { Ensures.NotNull(signature, nameof(signature)); Ensures.NotNull(values, nameof(values)); var inputParameter = new List <Parameter>(); var methodParameter = signature.GetParameters(); for (var i = 0; i < values.Length; ++i) { var parameter = methodParameter[i]; if (!parameter.IsOut && !parameter.ParameterType.IsByRef) { var value = values[i]; inputParameter.Add(new Parameter( parameter.Name ?? "unknown", parameter.ParameterType, value)); } } InputParameterCollection = inputParameter; }
/// <summary> /// Emits code to create a new <see cref="Invocation"/> instance for the given method signature and features. /// </summary> /// <param name="body"> The body of the dynamic method. </param> /// <param name="invocationVariable"> The local <see cref="Invocation"/> variable. </param> /// <param name="methodSignatureVariable"> The emitted local <see cref="MethodInfo"/> variable. </param> /// <param name="invocationFeatureVariables"> A colleciton of local <see cref="IInvocationFeature"/> variables. </param> /// <remarks> /// Emits the following source code: /// <![CDATA[ /// invocation = new Invocation(methodSignature, feature1, feature2, ... featureN); /// ]]> /// </remarks> public static void EmitNewInvocation( this ILGenerator body, LocalBuilder invocationVariable, LocalBuilder methodSignatureVariable, IReadOnlyList <LocalBuilder> invocationFeatureVariables) { Ensures.NotNull(invocationVariable, nameof(invocationVariable)); Ensures.NotNull(methodSignatureVariable, nameof(methodSignatureVariable)); Ensures.NotNull(invocationFeatureVariables, nameof(invocationFeatureVariables)); // methodSignature body.Emit(OpCodes.Ldloc, methodSignatureVariable.LocalIndex); if (invocationFeatureVariables == null || invocationFeatureVariables.Count == 0) { // Array.Empty<IInvocationFeature>() body.Emit(OpCodes.Call, ArrayEmptyInvocationFeature.Value); } else { // feature1, feature2, ... featurenN body.Emit(OpCodes.Ldc_I4, invocationFeatureVariables.Count); body.Emit(OpCodes.Newarr, typeof(IInvocationFeature)); for (var i = 0; i < invocationFeatureVariables.Count; ++i) { var feature = invocationFeatureVariables[i]; body.Emit(OpCodes.Dup); body.Emit(OpCodes.Ldc_I4, i); body.Emit(OpCodes.Ldloc, feature.LocalIndex); body.Emit(OpCodes.Stelem_Ref); } } // invocation = new Invocation(...) body.Emit(OpCodes.Newobj, CreateInvocation.Value); body.Emit(OpCodes.Stloc, invocationVariable.LocalIndex); }
/// <inheritdoc cref="ICompositionRoot" /> public void Compose(IServiceRegistry serviceRegistry) { Ensures.NotNull(serviceRegistry, nameof(serviceRegistry)); serviceRegistry.Register <IDynamicProxyFactory, DynamicProxyFactory>(); serviceRegistry.Register <IAssemblyEmitter, AssemblyEmitter>(); serviceRegistry.Register <IDependencyEmitter, DependencyEmitter>(); serviceRegistry.Register <IMethodEmitterFactory, MethodEmitterFactory>(); serviceRegistry.Register <IMethodDecoratorEmitterFactory, MethodDecoratorEmitterFactory>(); serviceRegistry.Register <IPropertyEmitterFactory, PropertyEmitterFactory>(); serviceRegistry.Register <IPropertyDecoratorEmitterFactory, PropertyDecoratorEmitterFactory>(); serviceRegistry.Register <TypeBuilder, ITypeEmitter>((factory, typeBuilder) => { var dependencyEmitter = factory.GetInstance <IDependencyEmitter>(); var methodEmitterFactory = factory.GetInstance <IMethodEmitterFactory>(); var propertyEmitterFactory = factory.GetInstance <IPropertyEmitterFactory>(); return(new TypeEmitter( typeBuilder, dependencyEmitter, methodEmitterFactory, propertyEmitterFactory)); }); serviceRegistry.Register <TypeBuilder, ITypeDecoratorEmitter>((factory, typeBuilder) => { var dependencyEmitter = factory.GetInstance <IDependencyEmitter>(); var methodEmitterFactory = factory.GetInstance <IMethodDecoratorEmitterFactory>(); var propertyEmitterFactory = factory.GetInstance <IPropertyDecoratorEmitterFactory>(); return(new TypeDecoratorEmitter( typeBuilder, dependencyEmitter, methodEmitterFactory, propertyEmitterFactory)); }); serviceRegistry.Register <IInterceptorFactory, InterceptorFactory>(); serviceRegistry.Register <IMockedDependencyFactory, MockedDependencyFactory>(); }
/// <summary> /// Creates a new instance of the <see cref="ParameterRef"/> type. /// </summary> /// <param name="signature"> The intercepted method's signature. </param> /// <param name="values"> The intercepted method's ref parameters. </param> public ParameterRef(MethodInfo signature, object?[] values) { Ensures.NotNull(signature, nameof(signature)); Ensures.NotNull(values, nameof(values)); var refParameter = new List <Parameter>(); var methodParameter = signature.GetParameters(); for (var i = 0; i < methodParameter.Length; ++i) { var parameter = methodParameter[i]; if (parameter.ParameterType.IsByRef) { var value = values[i]; var type = parameter.ParameterType.GetElementType() ?? throw new MethodInfoException(typeof(Type), nameof(Type.GetElementType)); refParameter.Add(new Parameter( parameter.Name ?? "unknown", type, value)); } } RefParameterCollection = refParameter; }