private IProjectionMetadata GetMetadataForModel(PageDescriptor descriptor, ProcArgs args, IDomainOptions options) { Type pageType = this.GetModelTypeFromPage(descriptor.PageType); Type argsType = args.ModelType ?? typeof(object); ISchema pageSchema = options.Schemas.GetSchema(pageType); ISchema argsSchema = options.Schemas.GetSchema(argsType); IProjectionMetadata pageMetadata = pageSchema.Require <IProjectionMetadata>(); IProjectionMetadata argsMetadata = argsSchema.Require <IProjectionMetadata>(); if (argsMetadata.Item != null && pageMetadata.Type.IsAssignableFrom(argsMetadata.Item.Type)) { return(argsMetadata.Item); } else if (pageMetadata.Type.IsAssignableFrom(argsMetadata.Type)) { return(argsMetadata); } else if (argsMetadata.Type.IsAssignableFrom(pageMetadata.Type)) { return(pageMetadata); } else { throw new InvalidOperationException($"No conversion found between page type '{pageMetadata.Type.FullName}' and requested type '{argsMetadata.Type.FullName}'."); } }
private IProcResult ExecuteAndGetResult(string procName, object model, ProcArgs args) { IProcLocator locator = this.Context?.Locator ?? new ProcLocator(); IProcEngine engine = this.Context?.Engine ?? new ProcEngine(null); PageDescriptor descriptor = locator.FindPage(procName, this.GetType()); ProcFactory factory = engine.Proc(descriptor, args); return(factory(model)); }
public ProcCacheKey(PageDescriptor descriptor, ProcArgs args) { if (descriptor == null) { throw new ArgumentNullException(nameof(descriptor)); } if (args == null) { throw new ArgumentNullException(nameof(args)); } this.PageType = descriptor.PageType; this.ModelType = args.ModelType; this.ResultType = args.ResultType; }
private IProjectionMetadata GetMetadataForResult(PageDescriptor descriptor, ProcArgs args, IDomainOptions options) { Type itemType = this.GetResultTypeFromPage(descriptor.PageType); Type pageType = typeof(IList <>).MakeGenericType(itemType); Type argsType = args.ResultType ?? typeof(IReadOnlyList <object>); ISchema pageSchema = options.Schemas.GetSchema(pageType); ISchema argsSchema = options.Schemas.GetSchema(argsType); IProjectionMetadata pageMetadata = pageSchema.Require <IProjectionMetadata>(); IProjectionMetadata argsMetadata = argsSchema.Require <IProjectionMetadata>(); if (pageMetadata.Item != null && argsMetadata.Item != null && pageMetadata.Item.Type.IsAssignableFrom(argsMetadata.Item.Type)) { return(argsMetadata.Item); } else if (pageMetadata.Item != null && argsMetadata.Item != null && argsMetadata.Item.Type.IsAssignableFrom(pageMetadata.Item.Type)) { return(pageMetadata.Item); } else if (pageMetadata.Item != null && pageMetadata.Item.Type.IsAssignableFrom(argsMetadata.Type)) { return(argsMetadata); } else if (argsMetadata.Item != null && argsMetadata.Item.Type.IsAssignableFrom(pageMetadata.Type)) { return(pageMetadata); } else if (argsMetadata.Type.IsAssignableFrom(pageMetadata.Type)) { return(pageMetadata); } else if (pageMetadata.Type.IsAssignableFrom(argsMetadata.Type)) { return(argsMetadata); } else { throw new InvalidOperationException($"No conversion found between page type '{pageMetadata.Type.GetSanitizedFullName()}' and requested type '{argsMetadata.Type.GetSanitizedFullName()}'."); } }
public ProcFactory Proc(PageDescriptor descriptor, ProcArgs args) { if (descriptor == null) { throw new ArgumentNullException(nameof(descriptor)); } if (args == null) { throw new ArgumentNullException(nameof(args)); } if (descriptor.DomainType == null) { throw ProcExecutionException.DomainNotFound(descriptor.PageType); } ProcCacheKey key = new ProcCacheKey(descriptor, args); return(ProcCache.Procs.GetOrAdd(key, _ => this.CreateProcFactory(descriptor, args))); }
public ProcFactory Proc(PageDescriptor descriptor, ProcArgs args) { if (descriptor == null) { throw new ArgumentNullException(nameof(descriptor)); } if (args == null) { throw new ArgumentNullException(nameof(args)); } if (descriptor.DomainType == null) { throw new ProcExecutionException($"No domain found for page type '{descriptor.PageType.GetSanitizedFullName()}'. Make sure to implement IDomain in a parent namespace."); } ProcCacheKey key = new ProcCacheKey(descriptor, args); return(ProcCache.Procs.GetOrAdd(key, _ => this.CreateProcFactory(descriptor, args))); }
private ProcFactory CreateProcFactory(PageDescriptor descriptor, ProcArgs args) { IDomainOptions options = this.Options(descriptor.DomainType); PageDescriptor[] template = this.GetTemplateHierarchy(descriptor).Reverse().ToArray(); PageConstructor[] factories = template.Select(t => this.CreatePageConstructor(t.PageType)).Concat(new PageConstructor[1]).ToArray(); IProjectionMetadata resultMetadata = this.GetMetadataForResult(descriptor, args, options); IProjectionMetadata modelMetadata = this.GetMetadataForModel(descriptor, args, options); ISchema resultSchema = resultMetadata.Identity.Schema; ISchema modelSchema = modelMetadata.Identity.Schema; IProcLocator locator = descriptor.Locator; Type originType = descriptor.OriginType; IProcResult procFactory(object model) { ProcContext context = this.CreateContext(descriptor); ProjectionIdentity modelIdentity = new ProjectionIdentity(new Model(modelSchema, model)); ProjectionIdentity resultIdentity = new ProjectionIdentity(resultSchema); IProjection modelProjection = new Projection(modelIdentity, context, modelMetadata); IProjection resultProjection = new Projection(resultIdentity, context, resultMetadata); PageExecutionContext[] execution = template.Select(t => new PageExecutionContext() { Page = t }).ToArray(); execution[0].Buffer = new ProcBuffer(); for (int i = 0; i < execution.Length; i++) { PageConstructor nextFactory = factories[i + 1]; if (nextFactory != null) { PageExecutionContext nextContext = execution[i + 1]; execution[i].Body = () => { ISqlPage bodyPage = nextFactory(modelProjection, resultProjection); context.Stack.Push(nextContext); bodyPage.Execute(); context.Stack.Pop(); }; } } ISqlPage page = factories[0](modelProjection, resultProjection); context.Stack.Push(execution[0]); page.Execute(); return(new ProcResult() { Buffer = context.Execution.Buffer, Domain = options, }); } return(procFactory); }