public static void CreateFor(ContractInfo contractMembers, object contractObject, IInterlocutor interlocutor) { Dictionary <PropertyInfo, string> delegateToMethodsMap; Type type; CreateHandlerType(contractMembers, out delegateToMethodsMap, out type); var delegateHandler = Activator.CreateInstance(type, interlocutor); //myContract.Callback += delegateHandler.CallbackDelegateHandler; foreach (var method in delegateToMethodsMap) { method.Key.SetValue(contractObject, Delegate.CreateDelegate(method.Key.PropertyType, delegateHandler, method.Value)); } }
public static void CreateFor(ContractInfo contractMembers, object contractObject, IInterlocutor interlocutor) { Dictionary <PropertyInfo, string> delegateToMethodsMap; Type type; CreateHandlerType(contractMembers, out delegateToMethodsMap, out type); var delegateHandler = Activator.CreateInstance(type, interlocutor); //Set handlers for origin contract delegate properties: foreach (var method in delegateToMethodsMap) { var del = delegateHandler .GetType() .GetMethod(method.Value) .CreateDelegate(method.Key.PropertyType, delegateHandler); method.Key.SetValue(contractObject, del); } }
public static ContractInfo Link <TInterface>(TInterface contract, IInterlocutor interlocutor) { var contractType = contract.GetType(); var interfaceType = typeof(TInterface); ContractInfo contractMemebers = GetContractMemebers(contractType, interfaceType); foreach (var method in contractMemebers.GetMethods()) { if (method.Value.ReturnParameter.ParameterType == typeof(void)) { //Say handler method: interlocutor.SetIncomeSayCallHandler(method.Key, args => method.Value.Invoke(contract, args)); } else { //Ask handler method: interlocutor.SetIncomeAskCallHandler(method.Key, args => method.Value.Invoke(contract, args)); } } OriginCallbackDelegatesHandlerFactory.CreateFor(contractMemebers, contract, interlocutor); return(contractMemebers); }
public static T CreateProxyContract <T>(IInterlocutor interlocutor) { var interfaceType = typeof(T); TypeBuilder typeBuilder = CreateProxyTypeBuilder <T>(); typeBuilder.AddInterfaceImplementation(interfaceType); const string interlocutorFieldName = "_interlocutor"; var outputApiFieldInfo = typeBuilder.DefineField( interlocutorFieldName, typeof(IInterlocutor), FieldAttributes.Private); var sayMehodInfo = interlocutor.GetType().GetMethod("Say", new[] { typeof(int), typeof(object[]) }); var contractMemebers = ParseContractInterface(typeof(T));// new ContractsMemberInfo(typeof(T)); foreach (var eventInfo in interfaceType.GetEvents()) { throw new InvalidContractMemeberException(eventInfo, interfaceType); } #region interface methods implementation foreach (var method in contractMemebers.GetMethods()) { var methodBuilder = EmitHelper.ImplementInterfaceMethod(method.Value, typeBuilder); var returnType = method.Value.ReturnType; MethodInfo askOrSayMethodInfo = null; if (returnType == typeof(void)) { askOrSayMethodInfo = sayMehodInfo; } else { askOrSayMethodInfo = interlocutor .GetType() .GetMethod("Ask", new[] { typeof(int), typeof(object[]) }) .MakeGenericMethod(returnType); } EmitHelper.GenerateSayOrAskMethodBody( messageTypeId: method.Key, interlocutorSayOrAskMethodInfo: askOrSayMethodInfo, interlocutorFieldInfo: outputApiFieldInfo, methodBuilder: methodBuilder, callParameters: method.Value.GetParameters().Select(p => p.ParameterType).ToArray()); } #endregion var constructorCodeGeneration = new List <Action <ILGenerator> >(); #region interface delegate properties implementation foreach (var property in contractMemebers.GetProperties()) { var propertyBuilder = EmitHelper.ImplementInterfaceProperty(typeBuilder, property.Value); var delegateInfo = ReflectionHelper.GetDelegateInfoOrNull(propertyBuilder.PropertyBuilder.PropertyType); if (delegateInfo == null) { //the property is not an delegate throw new InvalidContractMemeberException(property.Value, interfaceType); } // Create handler for every delegate property var handleMethodNuilder = ImplementAndGenerateHandleMethod( typeBuilder, delegateInfo, propertyBuilder.FieldBuilder); constructorCodeGeneration.Add( iLGenerator => GenerateEventSubscribtion(iLGenerator, outputApiFieldInfo, property.Key, handleMethodNuilder)); } #endregion EmitHelper.ImplementPublicConstructor( typeBuilder, new [] { outputApiFieldInfo }, constructorCodeGeneration); var finalType = typeBuilder.CreateTypeInfo().AsType(); return((T)Activator.CreateInstance(finalType, interlocutor)); }