public async Task <ReportOutput> ExecuteReportOutputAsync(ReportDefinition reportDefinition, IDictionary <string, string> values) { ReportCommandContext context = new ReportCommandContext(reportDefinition, reportDefinition.Output.Command); if (!string.IsNullOrWhiteSpace(reportDefinition.ContextProvider)) { Type contextProviderType = Type.GetType(reportDefinition.ContextProvider, true, true); context.ContextProvider = ActivatorUtilities.CreateInstance(this.ServiceProvider, contextProviderType); } var reportCommand = await this.CommandBuilder.BuildCommandAsync(context, values); using (IServiceScope serviceScope = this.ServiceProvider.GetRequiredService <IServiceScopeFactory>().CreateScope()) { if (!reportDefinition.TryFindDataSourceDefinition(reportDefinition.Output, out DataSourceDefinition dataSourceDefinition)) { throw new InvalidOperationException($"Could not find data source definition '{reportDefinition.Output.DataSource}' in the report '{reportDefinition.Name}'."); } var dataSourceRegistrationOptionsSnapshot = serviceScope.ServiceProvider.GetRequiredService <IOptionsSnapshot <DataSourceRegistrationOptions> >(); var dataSourceRegistrationOptions = dataSourceRegistrationOptionsSnapshot.Get(dataSourceDefinition.Type); if (null == dataSourceRegistrationOptions.TypeHandle || IntPtr.Zero == dataSourceRegistrationOptions.TypeHandle.Value) { throw new InvalidOperationException($"No data source service is registered for data source type '{dataSourceDefinition.Type}'."); } Type dataSourceType = Type.GetTypeFromHandle(dataSourceRegistrationOptions.TypeHandle); IDataSource dataSource = (IDataSource)serviceScope.ServiceProvider.GetRequiredService(dataSourceType); await dataSource.OpenAsync(dataSourceDefinition); try { var dataset = await dataSource.GetDataAsync(reportCommand, reportDefinition.EnumerateFieldDefinitions().ToArray()); return(new ReportOutput(reportCommand, dataset)); } finally { await dataSource.CloseAsync(); } } }
public async Task <ReportCommand> BuildCommandAsync(ReportCommandContext context, IDictionary <string, string> values) { if (!this.TryParseCommandText(context.CommandDefinition.CommandText, out string commandText, out IList <string> parameterNames)) { throw new InvalidOperationException($"Failed to parse command '{context.CommandName}' in report '{context.ReportDefinition.Name}'."); } ReportCommand reportCommand = new ReportCommand(commandText, context.CommandDefinition); if (null == values) { values = new Dictionary <string, string>(new FilterNameComparer()); } else { values = new Dictionary <string, string>(values, new FilterNameComparer()); } foreach (string parameterName in parameterNames) { if (context.ReportDefinition.TryFindFilterDefinition(parameterName, out FilterDefinition filterDefinition)) { if (!values.TryGetValue(parameterName, out string rawValue)) { rawValue = null; } FilterValue filterValue = await this.FilterValueBinder.GetFilterValueAsync(context, filterDefinition, rawValue); ReportCommandParameter reportCommandParameter = new ReportCommandParameter(parameterName, filterValue); reportCommand.Parameters.Add(reportCommandParameter); } else { throw new InvalidOperationException($"Filter definition for command parameter '{parameterName}' could not be found. (Command name is '{context.CommandName}'.)"); } } return(reportCommand); }