示例#1
0
        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));
        }