internal override IStreamObserver <TKey, TPayload> CreatePipe(IStreamObserver <TKey, TPayload> observer) { var lookupKey = CacheKey.Create(); var generatedPipeType = cachedPipes.GetOrAdd(lookupKey, key => ColumnToRowTemplate.Generate(this)); Func <PlanNode, IQueryObject, PlanNode> planNode = ((PlanNode p, IQueryObject o) => new ColumnToRowPlanNode(p, o, typeof(TKey), typeof(TPayload))); var instance = Activator.CreateInstance(generatedPipeType.Item1, this, observer, planNode); var returnValue = (UnaryPipe <TKey, TPayload, TPayload>)instance; return(returnValue); }
internal static Tuple <Type, string> Generate <TKey, TPayload>(ColumnToRowStreamable <TKey, TPayload> stream) { Contract.Requires(stream != null); Contract.Ensures(Contract.Result <Tuple <Type, string> >() != null); Contract.Ensures(typeof(UnaryPipe <TKey, TPayload, TPayload>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1)); var keyType = typeof(TKey); var payloadType = typeof(TPayload); var assemblyReferences = new List <Assembly>(); assemblyReferences.AddRange(Transformer.AssemblyReferencesNeededFor(keyType)); assemblyReferences.AddRange(Transformer.AssemblyReferencesNeededFor(payloadType)); var generatedClassName = string.Format(CultureInfo.InvariantCulture, "ColumnToRowUnaryPipeGeneratedFrom_{0}_{1}_{2}", keyType.GetValidIdentifier(), payloadType.GetValidIdentifier(), ColumnToRowSequenceNumber++); var template = new ColumnToRowTemplate(generatedClassName, keyType, payloadType); var expandedCode = template.TransformText(); assemblyReferences.Add(typeof(IStreamable <,>).GetTypeInfo().Assembly); assemblyReferences.Add(Transformer.GeneratedStreamMessageAssembly <TKey, TPayload>()); generatedClassName = generatedClassName.AddNumberOfNecessaryGenericArguments(keyType, payloadType); var a = Transformer.CompileSourceCode(expandedCode, assemblyReferences, out string errorMessages); if (payloadType.IsAnonymousTypeName()) { if (errorMessages == null) { errorMessages = string.Empty; } errorMessages += "\nCodegen Warning: The payload type for ColumnToRow is anonymous, causing the use of Activator.CreateInstance in an inner loop. This will lead to poor performance.\n"; } var t = a.GetType(generatedClassName); if (t.GetTypeInfo().IsGenericType) { var list = keyType.GetAnonymousTypes(); list.AddRange(payloadType.GetAnonymousTypes()); return(Tuple.Create(t.MakeGenericType(list.ToArray()), errorMessages)); } else { return(Tuple.Create(t, errorMessages)); } }