Beispiel #1
0
        public static void GetGeneratedCode(Type keyType, Type payloadType, out string generatedClassName, out string expandedCode, out List <Assembly> assemblyReferences)
        {
            var template = new SafeBatchTemplate();

            assemblyReferences = new List <Assembly>
            {
                Transformer.SystemRuntimeSerializationDll // needed for [DataContract] and [DataMember] in generated code
            };

            assemblyReferences.AddRange(Transformer.AssemblyReferencesNeededFor(keyType));
            template.keyType = keyType;

            assemblyReferences.AddRange(Transformer.AssemblyReferencesNeededFor(payloadType));
            template.payloadType            = payloadType;
            template.needsPolymorphismCheck =
                !payloadType.GetTypeInfo().IsValueType&&
                !payloadType.IsAnonymousTypeName() &&
                !payloadType.GetTypeInfo().IsSealed;
            template.payloadMightBeNull = payloadType.CanContainNull();

            generatedClassName = Transformer.GetBatchClassName(keyType, payloadType);
            template.CLASSNAME = generatedClassName.CleanUpIdentifierName();
            generatedClassName = generatedClassName.AddNumberOfNecessaryGenericArguments(keyType, payloadType);

            var payloadRepresentation = new ColumnarRepresentation(payloadType);

            template.fields         = payloadRepresentation.AllFields;
            template.noPublicFields = payloadRepresentation.noFields;

            expandedCode = template.TransformText();
        }
Beispiel #2
0
        /// <summary>
        /// Generate a batch class definition from the types <typeparamref name="TKey"/> and <typeparamref name="TPayload"/>.
        /// Compile the definition, dynamically load the assembly containing it, and return the Type representing the
        /// batch class.
        /// </summary>
        /// <typeparam name="TKey">
        /// The key type for the batch class.
        /// </typeparam>
        /// <typeparam name="TPayload">
        /// The payload type for which a batch class is generated. The batch class will have a field F of type T[] for every field
        /// F of type T in the type <typeparamref name="TPayload"/>.
        /// </typeparam>
        /// <returns>
        /// A type that is defined to be a subtype of Batch&lt;<typeparamref name="TKey"/>,<typeparamref name="TPayload"/>&gt;.
        /// </returns>
        public static Type GenerateBatchClass <TKey, TPayload>()
        {
#if CODEGEN_TIMING
            Stopwatch sw = new Stopwatch();
            sw.Start();
#endif

            var keyType     = typeof(TKey);
            var payloadType = typeof(TPayload);
            SafeBatchTemplate.GetGeneratedCode(keyType, payloadType, out string generatedClassName, out string expandedCode, out List <Assembly> assemblyReferences);

            assemblyReferences.Add(MemoryManager.GetMemoryPool <TKey, TPayload>().GetType().GetTypeInfo().Assembly);
            assemblyReferences.Add(SystemRuntimeSerializationDll);
            if (keyType != typeof(Empty))
            {
                assemblyReferences.Add(typeof(Empty).GetTypeInfo().Assembly);
                assemblyReferences.Add(StreamMessageManager.GetStreamMessageType <Empty, TPayload>().GetTypeInfo().Assembly);
            }

            var a = CompileSourceCode(expandedCode, assemblyReferences, out string errorMessages);
            var t = a.GetType(generatedClassName);
            if (t.GetTypeInfo().IsGenericType)
            {
                var list = keyType.GetAnonymousTypes();
                list.AddRange(payloadType.GetAnonymousTypes());
                t = t.MakeGenericType(list.ToArray());
            }

#if CODEGEN_TIMING
            sw.Stop();
            Console.WriteLine("Time to generate and instantiate a batch for {0},{1}: {2}ms",
                              keyType.GetCSharpSourceSyntax(), payload.GetCSharpSourceSyntax(), sw.ElapsedMilliseconds);
#endif
            return(t);
        }