public override IReadOnlyCollection <ParameterMapping> ProvideParameterMapping(System.Reflection.MethodInfo methodInfo) { List <ParameterMapping> mapping = new List <ParameterMapping>(); var email = methodInfo.GetParameters()[0]; var from = new ParameterMapping("from"); mapping.Add(from); from.AddSource(email, (EmailChange e) => e.From); var to = new ParameterMapping("to"); to.AddSource(email, (EmailChange e) => e.To); mapping.Add(to); var when = new ParameterMapping("when"); when.AddSource(email, (EmailChange e) => e.When); mapping.Add(when); var domain = new ParameterMapping("domain"); domain.AddSource(email, (EmailChange e) => e.GetDomain()); mapping.Add(domain); return(mapping.AsReadOnly()); }
public override IReadOnlyCollection <ParameterMapping> ProvideParameterMapping(System.Reflection.MethodInfo methodInfo) { List <ParameterMapping> mapping = new List <ParameterMapping>(); var email = methodInfo.GetParameters()[0]; var from = new ParameterMapping("from"); mapping.Add(from); from.AddSource(email, (OtherClass o) => o.AMethodNotShared()); return(mapping.AsReadOnly()); }
public override IReadOnlyCollection <ParameterMapping> ProvideParameterMapping(System.Reflection.MethodInfo methodInfo) { var mappings = new List <ParameterMapping>(); var mapping = new ParameterMapping("data"); mappings.Add(mapping); foreach (var p in methodInfo.GetParameters().Reverse()) { mapping.AddSource(p); } return(mappings.AsReadOnly()); }
/// <summary> /// Emits a method to complement an interface method. The complement method will have a suffix such as _Completed, /// and will take one parameter. /// </summary> /// <param name="invocationContext">The InvocationContext for this call.</param> /// <param name="suffix">The suffix to use on the method.</param> /// <param name="parameterType">The type of the parameter of the method.</param> /// <param name="parameterName">The name of the parameter of the method.</param> /// <param name="beginMethod">The begin method for this interface call.</param> /// <param name="eventId">The next available event ID.</param> /// <param name="autoKeyword">The auto-keyword to use if enabled.</param> /// <param name="faultedMethod">A faulted method to call or null if no other faulted method is available.</param> /// <returns>The MethodBuilder for the method.</returns> private MethodBuilder EmitMethodComplementImpl(InvocationContext invocationContext, string suffix, Type parameterType, string parameterName, MethodInfo beginMethod, ref int eventId, EventKeywords autoKeyword, MethodBuilder faultedMethod) { var interfaceMethod = invocationContext.MethodInfo; // if there is a NonEvent attribute, then no need to emit this method if (interfaceMethod.GetCustomAttribute <NonEventAttribute>() != null) { return(null); } // if the method ends in _Completed, then don't emit another one if (interfaceMethod.Name.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)) { return(null); } var methodName = beginMethod.Name + suffix; // if the interface already has a _Completed method with the same parameter, don't emit a new one var parameterTypes = parameterType == typeof(void) ? Type.EmptyTypes : new Type[] { parameterType }; if (interfaceMethod.DeclaringType.GetMethod(methodName, parameterTypes) != null) { return(null); } // create a single parameter for the return value, and a context parameter if its supported var parameterMappings = new List <ParameterMapping>(); if (parameterType != typeof(void)) { var mapping = new ParameterMapping(parameterName); mapping.AddSource(new ParameterDefinition(parameterName, 0, parameterType)); parameterMappings.Add(mapping); } if (SupportsContext(invocationContext)) { parameterMappings.Add(new ParameterMapping(Context)); } // determine if this is a non-event or an event // if an event, but there is no event attribute, just add one to the last event id EventAttribute startEventAttribute = interfaceMethod.GetCustomAttribute <EventAttribute>() ?? new EventAttribute(eventId); EventAttribute eventAttribute = _eventAttributeProvider.CopyEventAttribute(startEventAttribute, invocationContext, eventId); eventId = Math.Max(eventId, eventAttribute.EventId + 1); if (eventAttribute.Keywords == EventKeywords.None) { eventAttribute.Keywords = autoKeyword; } // define the internal method MethodBuilder m = _typeBuilder.DefineMethod(methodName, MethodAttributes.Public, typeof(void), parameterMappings.Select(p => p.CleanTargetType).ToArray()); if (parameterMappings.Any()) { m.DefineParameter(1, ParameterAttributes.None, parameterMappings[0].Name); } m.SetCustomAttribute(EventAttributeHelper.ConvertEventAttributeToAttributeBuilder(eventAttribute)); // if we have a return type, then we need to implement two methods if (parameterTypes.Length == 1) { EmitCallWriteEvent(invocationContext, m, eventAttribute, parameterMappings); // emit an overloaded wrapper method that calls the method when it's enabled // note this is a non-event so EventSource doesn't try to log it MethodBuilder im = _typeBuilder.DefineMethod(methodName, MethodAttributes.Public); ProxyHelper.CopyGenericSignature(interfaceMethod, im); im.SetReturnType(parameterTypes[0]); im.SetParameters(parameterTypes); // mark the method as a non-event im.SetCustomAttribute(EventAttributeHelper.CreateNonEventAttribute()); // put the return value on the stack so we can return the value as a passthrough im.GetILGenerator().Emit(OpCodes.Ldarg_1); if (EmitIsEnabled(im, eventAttribute)) { EmitTaskCompletion(im, parameterType, faultedMethod); EmitDirectProxy(invocationContext, im, m, parameterMappings); } return(im); } else { // the method does not have a return value // so create the internal method that calls WriteEvent ProxyHelper.EmitDefaultValue(m.GetILGenerator(), m.ReturnType); if (EmitIsEnabled(m, eventAttribute)) { EmitCallWriteEvent(invocationContext, m, eventAttribute, parameterMappings); } return(m); } }
public override IReadOnlyCollection<ParameterMapping> ProvideParameterMapping(System.Reflection.MethodInfo methodInfo) { List<ParameterMapping> mapping = new List<ParameterMapping>(); var email = methodInfo.GetParameters()[0]; var from = new ParameterMapping("from"); mapping.Add(from); from.AddSource(email, (EmailChange e) => e.From); var to = new ParameterMapping("to"); to.AddSource(email, (EmailChange e) => e.To); mapping.Add(to); var when = new ParameterMapping("when"); when.AddSource(email, (EmailChange e) => e.When); mapping.Add(when); var domain = new ParameterMapping("domain"); domain.AddSource(email, (EmailChange e) => e.GetDomain()); mapping.Add(domain); return mapping.AsReadOnly(); }
public override IReadOnlyCollection<ParameterMapping> ProvideParameterMapping(System.Reflection.MethodInfo methodInfo) { List<ParameterMapping> mapping = new List<ParameterMapping>(); var email = methodInfo.GetParameters()[0]; var from = new ParameterMapping("from"); mapping.Add(from); from.AddSource(email, (OtherClass o) => o.AMethodNotShared()); return mapping.AsReadOnly(); }
public override IReadOnlyCollection<ParameterMapping> ProvideParameterMapping(System.Reflection.MethodInfo methodInfo) { var mappings = new List<ParameterMapping>(); var mapping = new ParameterMapping("data"); mappings.Add(mapping); foreach (var p in methodInfo.GetParameters().Reverse()) mapping.AddSource(p); return mappings.AsReadOnly(); }
/// <summary> /// Emits a method to complement an interface method. The complement method will have a suffix such as _Completed, /// and will take one parameter. /// </summary> /// <param name="invocationContext">The InvocationContext for this call.</param> /// <param name="suffix">The suffix to use on the method.</param> /// <param name="parameterType">The type of the parameter of the method.</param> /// <param name="parameterName">The name of the parameter of the method.</param> /// <param name="beginMethod">The begin method for this interface call.</param> /// <param name="eventId">The next available event ID.</param> /// <param name="autoKeyword">The auto-keyword to use if enabled.</param> /// <param name="faultedMethod">A faulted method to call or null if no other faulted method is available.</param> /// <returns>The MethodBuilder for the method.</returns> private MethodBuilder EmitMethodComplementImpl(InvocationContext invocationContext, string suffix, Type parameterType, string parameterName, MethodInfo beginMethod, ref int eventId, EventKeywords autoKeyword, MethodBuilder faultedMethod) { var interfaceMethod = invocationContext.MethodInfo; // if there is a NonEvent attribute, then no need to emit this method if (interfaceMethod.GetCustomAttribute<NonEventAttribute>() != null) return null; // if the method ends in _Completed, then don't emit another one if (interfaceMethod.Name.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)) return null; var methodName = beginMethod.Name + suffix; // if the interface already has a _Completed method with the same parameter, don't emit a new one var parameterTypes = parameterType == typeof(void) ? Type.EmptyTypes : new Type[] { parameterType }; if (interfaceMethod.DeclaringType.GetMethod(methodName, parameterTypes) != null) return null; // create a single parameter for the return value, and a context parameter if its supported var parameterMappings = new List<ParameterMapping>(); if (parameterType != typeof(void)) { var mapping = new ParameterMapping(parameterName); mapping.AddSource(new ParameterDefinition(parameterName, 0, parameterType)); parameterMappings.Add(mapping); } if (SupportsContext(invocationContext)) parameterMappings.Add(new ParameterMapping(Context)); // determine if this is a non-event or an event // if an event, but there is no event attribute, just add one to the last event id EventAttribute startEventAttribute = interfaceMethod.GetCustomAttribute<EventAttribute>() ?? new EventAttribute(eventId); EventAttribute eventAttribute = _eventAttributeProvider.CopyEventAttribute(startEventAttribute, invocationContext, eventId); eventId = Math.Max(eventId, eventAttribute.EventId + 1); if (eventAttribute.Keywords == EventKeywords.None) eventAttribute.Keywords = autoKeyword; // define the internal method MethodBuilder m = _typeBuilder.DefineMethod(methodName, MethodAttributes.Public, typeof(void), parameterMappings.Select(p => p.CleanTargetType).ToArray()); if (parameterMappings.Any()) m.DefineParameter(1, ParameterAttributes.None, parameterMappings[0].Name); m.SetCustomAttribute(EventAttributeHelper.ConvertEventAttributeToAttributeBuilder(eventAttribute)); // if we have a return type, then we need to implement two methods if (parameterTypes.Length == 1) { EmitCallWriteEvent(invocationContext, m, eventAttribute, parameterMappings); // emit an overloaded wrapper method that calls the method when it's enabled // note this is a non-event so EventSource doesn't try to log it MethodBuilder im = _typeBuilder.DefineMethod(methodName, MethodAttributes.Public); ProxyHelper.CopyGenericSignature(interfaceMethod, im); im.SetReturnType(parameterTypes[0]); im.SetParameters(parameterTypes); // mark the method as a non-event im.SetCustomAttribute(EventAttributeHelper.CreateNonEventAttribute()); // put the return value on the stack so we can return the value as a passthrough im.GetILGenerator().Emit(OpCodes.Ldarg_1); if (EmitIsEnabled(im, eventAttribute)) { EmitTaskCompletion(im, parameterType, faultedMethod); EmitDirectProxy(invocationContext, im, m, parameterMappings); } return im; } else { // the method does not have a return value // so create the internal method that calls WriteEvent ProxyHelper.EmitDefaultValue(m.GetILGenerator(), m.ReturnType); if (EmitIsEnabled(m, eventAttribute)) EmitCallWriteEvent(invocationContext, m, eventAttribute, parameterMappings); return m; } }