protected override void Load(ContainerBuilder builder) { builder.Register((ctx) => _logger).As <IPipelineLogger>(); builder.Register <IReader>(c => new DefaultReader(new FileReader(), new WebReader())).As <IReader>(); // register short-hand for t attribute var tm = new TransformModule(new Process { Name = "Transform Shorthand" }, _methods, _shortHand, _logger) { Plugins = false }; // adding additional transforms here tm.AddTransform(new TransformHolder((c) => new UsernameTransform(), new UsernameTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new UserIdTransform(), new UserIdTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new UserEmailTransform(), new UserEmailTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardRazorTransform(), new OrchardRazorTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardFluidTransform(), new OrchardFluidTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardJintTransform(), new OrchardJintTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new ToLocalTimeTransform(), new ToLocalTimeTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new GetEncodedUrlTransform(), new GetEncodedUrlTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new GetDisplayUrlTransform(), new GetDisplayUrlTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardTimeZoneTransform(), new OrchardTimeZoneTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new FilePartTransform(), new FilePartTransform().GetSignatures())); builder.RegisterModule(tm); // register short-hand for v attribute var vm = new ValidateModule(new Process { Name = "ValidateShorthand" }, _methods, _shortHand, _logger) { Plugins = false }; // adding additional validators here builder.RegisterModule(vm); // register the validator short hand builder.Register((c, p) => _shortHand).Named <ShorthandRoot>(ValidateModule.FieldsName).InstancePerLifetimeScope(); builder.Register((c, p) => _shortHand).Named <ShorthandRoot>(ValidateModule.ParametersName).InstancePerLifetimeScope(); builder.Register((c, p) => new ShorthandCustomizer(c.ResolveNamed <ShorthandRoot>(ValidateModule.FieldsName), new[] { "fields", "calculated-fields", "calculatedfields" }, "v", "validators", "method")).Named <IDependency>(ValidateModule.FieldsName).InstancePerLifetimeScope(); builder.Register((c, p) => new ShorthandCustomizer(c.ResolveNamed <ShorthandRoot>(ValidateModule.ParametersName), new[] { "parameters" }, "v", "validators", "method")).Named <IDependency>(ValidateModule.ParametersName).InstancePerLifetimeScope(); // register the transform short hand builder.Register((c, p) => _shortHand).Named <ShorthandRoot>(TransformModule.FieldsName).InstancePerLifetimeScope(); builder.Register((c, p) => _shortHand).Named <ShorthandRoot>(TransformModule.ParametersName).InstancePerLifetimeScope(); builder.Register((c, p) => new ShorthandCustomizer(c.ResolveNamed <ShorthandRoot>(TransformModule.FieldsName), new[] { "fields", "calculated-fields", "calculatedfields" }, "t", "transforms", "method")).Named <IDependency>(TransformModule.FieldsName).InstancePerLifetimeScope(); builder.Register((c, p) => new ShorthandCustomizer(c.ResolveNamed <ShorthandRoot>(TransformModule.ParametersName), new[] { "parameters" }, "t", "transforms", "method")).Named <IDependency>(TransformModule.ParametersName).InstancePerLifetimeScope(); // the shorthand registrations are stored in the builder's properties for plugins to add to builder.Properties["ShortHand"] = _shortHand; builder.Properties["Methods"] = _methods; // register transform modules here so they can add their shorthand builder.RegisterModule(new JsonTransformModule()); builder.RegisterModule(new HumanizeModule()); builder.RegisterModule(new FileModule()); builder.RegisterModule(new LambdaParserModule()); builder.RegisterModule(new AwsTransformModule()); // register validator modules here so they can register their short-hand builder.RegisterModule(new JintValidateModule()); builder.Register((c, p) => _methods).Named <HashSet <string> >("Methods").InstancePerLifetimeScope(); builder.Register((c, p) => _shortHand).As <ShorthandRoot>().InstancePerLifetimeScope(); }
public ILifetimeScope CreateScope(Process process, IPipelineLogger logger) { var builder = new ContainerBuilder(); #if PLUGINS builder.Properties["Process"] = process; #endif builder.Register(ctx => process).As <Process>(); builder.RegisterInstance(logger).As <IPipelineLogger>().SingleInstance(); // register short-hand for t attribute, allowing for additional transforms var transformModule = new TransformModule(process, _methods, _shortHand, logger); foreach (var t in _transforms) { transformModule.AddTransform(t); } builder.RegisterModule(transformModule); // register short-hand for v attribute, allowing for additional validators var validateModule = new ValidateModule(process, _methods, _shortHand, logger); foreach (var v in _validators) { validateModule.AddValidator(v); } builder.RegisterModule(validateModule); builder.RegisterModule(new InternalModule(process)); #if PLUGINS // just in case other modules need to see these builder.Properties["ShortHand"] = _shortHand; builder.Properties["Methods"] = _methods; #endif // allowing for additional modules foreach (var module in _modules) { builder.RegisterModule(module); } // Process Context builder.Register <IContext>((ctx, p) => new PipelineContext(logger, process)).As <IContext>(); // Process Output Context builder.Register(ctx => { var context = ctx.Resolve <IContext>(); return(new OutputContext(context)); }).As <OutputContext>(); // Connection and Process Level Output Context foreach (var connection in process.Connections) { builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(connection.Key); if (connection.Name != "output") { continue; } // register output for connection builder.Register(ctx => { var context = ctx.ResolveNamed <IConnectionContext>(connection.Key); return(new OutputContext(context)); }).Named <OutputContext>(connection.Key); } // Entity Context and RowFactory foreach (var entity in process.Entities) { builder.Register <IContext>((ctx, p) => new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)).Named <IContext>(entity.Key); builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); return(new InputContext(context)); }).Named <InputContext>(entity.Key); builder.Register <IRowFactory>((ctx, p) => new RowFactory(p.Named <int>("capacity"), entity.IsMaster, false)).Named <IRowFactory>(entity.Key); builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); return(new OutputContext(context)); }).Named <OutputContext>(entity.Key); var connection = process.Connections.First(c => c.Name == entity.Connection); builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(entity.Key); } // entity pipelines foreach (var entity in process.Entities) { builder.Register(ctx => { var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline; var context = ctx.ResolveNamed <IContext>(entity.Key); context.Debug(() => $"Registering {type} for entity {entity.Alias}."); var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController(); var pipeline = new DefaultPipeline(outputController, context); // TODO: rely on IInputProvider's Read method instead (after every provider has one) pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null); // transforms if (!process.ReadOnly) { pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new IncrementTransform(context)); pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System))); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any()))); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); if (!process.ReadOnly) { pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new LogTransform(context)); // writer, TODO: rely on IOutputProvider instead pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null); // updater pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key)); return(pipeline); }).Named <IPipeline>(entity.Key); } // process pipeline builder.Register(ctx => { var calc = process.ToCalculatedFieldsProcess(); var entity = calc.Entities.First(); var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity); var outputContext = new OutputContext(context); context.Debug(() => $"Registering {process.Pipeline} pipeline."); var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController(); var pipeline = new DefaultPipeline(outputController, context); // no updater necessary pipeline.Register(new NullUpdater(context, false)); if (!process.CalculatedFields.Any()) { pipeline.Register(new NullReader(context, false)); pipeline.Register(new NullWriter(context, false)); return(pipeline); } // register transforms pipeline.Register(new IncrementTransform(context)); pipeline.Register(new LogTransform(context)); pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields)); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.CalculatedFields)); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity))); // register input and output pipeline.Register(ctx.IsRegistered <IRead>() ? ctx.Resolve <IRead>() : new NullReader(context)); pipeline.Register(ctx.IsRegistered <IWrite>() ? ctx.Resolve <IWrite>() : new NullWriter(context)); if (outputContext.Connection.Provider == "sqlserver") { pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), new DateTime(1753, 1, 1))); } return(pipeline); }).As <IPipeline>(); // process controller builder.Register <IProcessController>(ctx => { var pipelines = new List <IPipeline>(); // entity-level pipelines foreach (var entity in process.Entities) { var pipeline = ctx.ResolveNamed <IPipeline>(entity.Key); pipelines.Add(pipeline); if (entity.Delete && process.Mode != "init") { pipeline.Register(ctx.ResolveNamed <IEntityDeleteHandler>(entity.Key)); } } // process-level pipeline for process level calculated fields if (ctx.IsRegistered <IPipeline>()) { pipelines.Add(ctx.Resolve <IPipeline>()); } var context = ctx.Resolve <IContext>(); var controller = new ProcessController(pipelines, context); // output initialization if (process.Mode == "init" && ctx.IsRegistered <IInitializer>()) { controller.PreActions.Add(ctx.Resolve <IInitializer>()); } // flatten(ing) is first post-action var isAdo = Constants.AdoProviderSet().Contains(process.Output().Provider); if (process.Flatten && isAdo) { if (ctx.IsRegisteredWithName <IAction>(process.Output().Key)) { controller.PostActions.Add(ctx.ResolveNamed <IAction>(process.Output().Key)); } else { context.Error($"Could not find ADO Flatten Action for provider {process.Output().Provider}."); } } // actions foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*"))) { if (action.Before) { controller.PreActions.Add(ctx.ResolveNamed <IAction>(action.Key)); } if (action.After) { controller.PostActions.Add(ctx.ResolveNamed <IAction>(action.Key)); } } return(controller); }).As <IProcessController>(); var build = builder.Build(); return(build.BeginLifetimeScope()); }
public ILifetimeScope CreateScope(string cfg, IPipelineLogger logger, IDictionary <string, string> parameters = null, string placeHolderStyle = "@[]") { if (placeHolderStyle == null || placeHolderStyle.Length != 3) { throw new ArgumentException("The placeHolderStyle parameter must be three characters (e.g. @[], or @())"); } if (parameters == null) { parameters = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); } var builder = new ContainerBuilder(); builder.Register((ctx) => logger).As <IPipelineLogger>(); builder.Register <IReader>(c => new DefaultReader(new FileReader(), new WebReader())).As <IReader>(); // register short-hand for t attribute var transformModule = new TransformModule(new Process { Name = "TransformShorthand" }, _methods, _shortHand, logger); foreach (var t in _transforms) { transformModule.AddTransform(t); } builder.RegisterModule(transformModule); // register short-hand for v attribute var validateModule = new ValidateModule(new Process { Name = "ValidateShorthand" }, _methods, _shortHand, logger); foreach (var v in _validators) { validateModule.AddValidator(v); } builder.RegisterModule(validateModule); // register the validator short hand builder.Register((c, p) => _shortHand).Named <ShorthandRoot>(ValidateModule.FieldsName).InstancePerLifetimeScope(); builder.Register((c, p) => new ShorthandCustomizer(c.ResolveNamed <ShorthandRoot>(ValidateModule.FieldsName), new[] { "fields", "calculated-fields", "calculatedfields" }, "v", "validators", "method")).Named <IDependency>(ValidateModule.FieldsName).InstancePerLifetimeScope(); // register the transform short hand builder.Register((c, p) => _shortHand).Named <ShorthandRoot>(TransformModule.FieldsName).InstancePerLifetimeScope(); builder.Register((c, p) => _shortHand).Named <ShorthandRoot>(TransformModule.ParametersName).InstancePerLifetimeScope(); builder.Register((c, p) => new ShorthandCustomizer(c.ResolveNamed <ShorthandRoot>(TransformModule.FieldsName), new[] { "fields", "calculated-fields", "calculatedfields" }, "t", "transforms", "method")).Named <IDependency>(TransformModule.FieldsName).InstancePerLifetimeScope(); builder.Register((c, p) => new ShorthandCustomizer(c.ResolveNamed <ShorthandRoot>(TransformModule.ParametersName), new[] { "parameters" }, "t", "transforms", "method")).Named <IDependency>(TransformModule.ParametersName).InstancePerLifetimeScope(); #if PLUGINS // the shorthand registrations are stored in the builder's properties for plugins to add to builder.Properties["ShortHand"] = _shortHand; builder.Properties["Methods"] = _methods; #endif foreach (var module in _modules) { builder.RegisterModule(module); } builder.Register((c, p) => _methods).Named <HashSet <string> >("Methods").InstancePerLifetimeScope(); builder.Register((c, p) => _shortHand).As <ShorthandRoot>().InstancePerLifetimeScope(); builder.Register(ctx => { var transformed = TransformParameters(ctx, cfg); var dependancies = new List <IDependency>(); dependancies.Add(ctx.Resolve <IReader>()); dependancies.AddRange(_dependencies); dependancies.Add(new ParameterModifier(new PlaceHolderReplacer(placeHolderStyle[0], placeHolderStyle[1], placeHolderStyle[2]), "parameters", "name", "value")); dependancies.Add(ctx.ResolveNamed <IDependency>(TransformModule.FieldsName)); dependancies.Add(ctx.ResolveNamed <IDependency>(TransformModule.ParametersName)); dependancies.Add(ctx.ResolveNamed <IDependency>(ValidateModule.FieldsName)); var process = new Process(transformed ?? cfg, parameters, dependancies.ToArray()); if (process.Errors().Any()) { var c = new PipelineContext(logger, new Process() { Name = "Errors" }); c.Error("The configuration has errors."); foreach (var error in process.Errors()) { c.Error(error); } } return(process); }).As <Process>().InstancePerDependency(); return(builder.Build().BeginLifetimeScope()); }
public ILifetimeScope CreateScope(Process process, IPipelineLogger logger) { var builder = new ContainerBuilder(); // the modules below rely on this process being there builder.Properties["Process"] = process; builder.Register(ctx => process).As <Process>(); builder.RegisterInstance(logger).As <IPipelineLogger>().SingleInstance(); // register short-hand for t attribute, allowing for additional transforms var tm = new TransformModule(process, _methods, _shortHand, logger) { Plugins = false }; // adding additional transforms here tm.AddTransform(new TransformHolder((c) => new UsernameTransform(_httpContext, c), new UsernameTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new UserIdTransform(_httpContext, _userService, c), new UserIdTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new UserEmailTransform(_httpContext, _userService, c), new UserEmailTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardRazorTransform(c, _memoryCache, _signal), new OrchardRazorTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardFluidTransform(c, _memoryCache, _signal), new OrchardFluidTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardJintTransform(c, new DefaultReader(new FileReader(), new WebReader()), _memoryCache, _signal), new OrchardJintTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new ToLocalTimeTransform(c, _clock, _localClock), new ToLocalTimeTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new GetEncodedUrlTransform(_httpContext, c), new GetEncodedUrlTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new GetDisplayUrlTransform(_httpContext, c), new GetDisplayUrlTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardTimeZoneTransform(c), new OrchardTimeZoneTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new GeocodeTransform(c), new GeocodeTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new PlaceTransform(c), new PlaceTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new FilePartTransform(c, _fileService), new FilePartTransform().GetSignatures())); builder.RegisterModule(tm); // register short-hand for v attribute, allowing for additional validators var vm = new ValidateModule(process, _methods, _shortHand, logger) { Plugins = false }; // adding additional validators here builder.RegisterModule(vm); // using custom internal module that does not handle the nested transformalize actions builder.RegisterModule(new OrchardInternalModule(process)); // handling nested transformalize actions here instead foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*"))) { if (action.Type == "tfl") { builder.Register <IAction>(ctx => { return(new PipelineAction(action, _serviceProvider)); }).Named <IAction>(action.Key); } } // register providers var providers = new HashSet <string>(process.Connections.Select(c => c.Provider)); // relational databases builder.RegisterModule(new AdoProviderModule()); if (providers.Contains("sqlserver")) { builder.RegisterModule(new SqlServerModule() { ConnectionFactory = (c) => new ProfiledConnectionFactory(new SqlServerConnectionFactory(c)) }); } if (providers.Contains("postgresql")) { builder.RegisterModule(new PostgreSqlModule() { ConnectionFactory = (c) => new ProfiledConnectionFactory(new PostgreSqlConnectionFactory(c)) }); } if (providers.Contains("sqlite")) { builder.RegisterModule(new SqliteModule() { ConnectionFactory = (c) => new ProfiledConnectionFactory(new SqliteConnectionFactory(c)) }); } if (providers.Contains("mysql")) { builder.RegisterModule(new MySqlModule() { ConnectionFactory = (c) => new ProfiledConnectionFactory(new MySqlConnectionFactory(c)) }); } // search engines if (providers.Contains("elasticsearch")) { builder.RegisterModule(new ElasticsearchModule()); } // solr // lucene // importing, exporting var stream = _httpContext.HttpContext.Response.Body; if (providers.Contains("file")) { builder.RegisterModule(new CsvHelperProviderModule(stream)); } if (providers.Contains("excel")) { builder.RegisterModule(new OrchardExcelModule()); } // exporting if (providers.Contains("json")) { builder.RegisterModule(new JsonProviderModule(stream) { UseAsyncMethods = true }); } if (providers.Contains("geojson")) { builder.RegisterModule(new GeoJsonProviderModule(stream) { UseAsyncMethods = true }); } // misc if (providers.Contains("bogus")) { builder.RegisterModule(new BogusModule()); } if (providers.Contains("log") || process.Actions.Any(a => a.Type == "log")) { builder.RegisterModule(new OrchardLogModule(process)); } if (providers.Contains("mail")) { builder.RegisterModule(new MailModule()); } if (providers.Contains("aws")) { var services = new HashSet <string>(process.Connections.Where(c => c.Provider == "aws").Select(c => c.Service)); if (services.Contains("logs")) { builder.RegisterModule(new AwsCloudWatchProviderModule()); } if (services.Contains("connect")) { builder.RegisterModule(new AmazonConnectProviderModule()); } } // transform and validation modules need these properties builder.Properties["ShortHand"] = _shortHand; builder.Properties["Methods"] = _methods; // register transform modules here builder.RegisterModule(new JsonTransformModule()); builder.RegisterModule(new HumanizeModule()); builder.RegisterModule(new FileModule()); builder.RegisterModule(new AdoTransformModule()); builder.RegisterModule(new LambdaParserModule()); builder.RegisterModule(new AwsTransformModule()); // register validator modules here builder.RegisterModule(new JintValidateModule()); // process context builder.Register <IContext>((ctx, p) => new PipelineContext(logger, process)).As <IContext>(); // process output context builder.Register(ctx => { var context = ctx.Resolve <IContext>(); return(new OutputContext(context)); }).As <OutputContext>(); // connection and process level output context var formWriter = false; foreach (var connection in process.Connections) { builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(connection.Key); // there can only be one form writer if (!formWriter && connection.Table != "[default]" && connection.Provider != "[default]") { builder.Register(ctx => { var context = ctx.ResolveNamed <IConnectionContext>(connection.Key); var connectionFactory = ctx.ResolveNamed <IConnectionFactory>(connection.Key); return(new AdoFormCommandWriter(context, connectionFactory)); }).As <AdoFormCommandWriter>(); formWriter = true; } if (connection.Name != process.Output) { continue; } // register output for connection builder.Register(ctx => { var context = ctx.ResolveNamed <IConnectionContext>(connection.Key); return(new OutputContext(context)); }).Named <OutputContext>(connection.Key); } // entity context and rowFactory foreach (var entity in process.Entities) { builder.Register <IContext>((ctx, p) => new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)).Named <IContext>(entity.Key); builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); return(new InputContext(context)); }).Named <InputContext>(entity.Key); builder.Register <IRowFactory>((ctx, p) => new RowFactory(p.Named <int>("capacity"), entity.IsMaster, false)).Named <IRowFactory>(entity.Key); builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); return(new OutputContext(context)); }).Named <OutputContext>(entity.Key); var connection = process.Connections.First(c => c.Name == entity.Input); builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(entity.Key); } // entity pipelines foreach (var entity in process.Entities) { builder.Register(ctx => { var output = process.GetOutputConnection(); var context = ctx.ResolveNamed <IContext>(entity.Key); var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController(); var pipeline = new DefaultPipeline(outputController, context); if (entity.IsMaster) { if (GetReaderAlternate != null) { // Using an alternate reader (e.g. a ParameterRowReader that reads parameters into a row) var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); pipeline.Register(GetReaderAlternate(input, rowFactory)); } else if (GetReaderDecorator != null && ctx.IsRegisteredWithName(entity.Key, typeof(IRead))) { // Decorating the normally registered reader (e.g. ParameterRowReader updating a row from an AdoReader) // TODO: Support IInputProvider instead of just IRead var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); pipeline.Register(GetReaderDecorator(ctx.ResolveNamed <IRead>(entity.Key), input, rowFactory)); } else { pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null); } } else { // TODO: rely on IInputProvider's Read method instead (after every provider has one) pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null); } // transforms if (!process.ReadOnly) { pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new IncrementTransform(context)); pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System))); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any()))); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); if (!process.ReadOnly && !output.Provider.In("internal", "log")) { pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new LogTransform(context)); // writer, TODO: rely on IOutputProvider instead pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null); // updater pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key)); return(pipeline); }).Named <IPipeline>(entity.Key); } if (process.Entities.Count > 1 && process.Relationships.Any()) { // process pipeline builder.Register(ctx => { var calc = process.ToCalculatedFieldsProcess(); var entity = calc.Entities.First(); var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity); var outputContext = new OutputContext(context); context.Debug(() => $"Registering {process.Pipeline} pipeline."); var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController(); var pipeline = new DefaultPipeline(outputController, context); // no updater necessary pipeline.Register(new NullUpdater(context, false)); if (!process.CalculatedFields.Any()) { pipeline.Register(new NullReader(context, false)); pipeline.Register(new NullWriter(context, false)); return(pipeline); } // register transforms pipeline.Register(new IncrementTransform(context)); pipeline.Register(new LogTransform(context)); pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields)); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.CalculatedFields)); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity))); // register input and output pipeline.Register(ctx.IsRegistered <IRead>() ? ctx.Resolve <IRead>() : new NullReader(context)); pipeline.Register(ctx.IsRegistered <IWrite>() ? ctx.Resolve <IWrite>() : new NullWriter(context)); if (outputContext.Connection.Provider == "sqlserver") { pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), new DateTime(1753, 1, 1))); } return(pipeline); }).As <IPipeline>(); } // process controller builder.Register <IProcessController>(ctx => { var pipelines = new List <IPipeline>(); // entity-level pipelines foreach (var entity in process.Entities) { var pipeline = ctx.ResolveNamed <IPipeline>(entity.Key); pipelines.Add(pipeline); if (entity.Delete && process.Mode != "init") { pipeline.Register(ctx.ResolveNamed <IEntityDeleteHandler>(entity.Key)); } } // process-level pipeline for process level calculated fields if (ctx.IsRegistered <IPipeline>()) { pipelines.Add(ctx.Resolve <IPipeline>()); } var context = ctx.Resolve <IContext>(); var controller = new ProcessController(pipelines, context); // output initialization if (process.Mode == "init" && ctx.IsRegistered <IInitializer>()) { controller.PreActions.Add(ctx.Resolve <IInitializer>()); } // flatten(ing) is first post-action var output = process.GetOutputConnection(); var isAdo = _adoProviders.Contains(output.Provider); if (process.Flatten && isAdo) { if (ctx.IsRegisteredWithName <IAction>(output.Key)) { controller.PostActions.Add(ctx.ResolveNamed <IAction>(output.Key)); } else { context.Error($"Could not find ADO Flatten Action for provider {output.Provider}."); } } // actions foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*"))) { if (ctx.IsRegisteredWithName <IAction>(action.Key)) { if (action.Before) { controller.PreActions.Add(ctx.ResolveNamed <IAction>(action.Key)); } if (action.After) { controller.PostActions.Add(ctx.ResolveNamed <IAction>(action.Key)); } } else { if (action.Type != "internal") { _logger.Warn(() => $"The action {action.Name} with type {action.Type} isn't registered."); } } } foreach (var map in process.Maps.Where(m => !string.IsNullOrEmpty(m.Query))) { controller.PreActions.Add(new MapReaderAction(context, map, ctx.ResolveNamed <IMapReader>(map.Name))); } return(controller); }).As <IProcessController>(); var build = builder.Build(); return(build.BeginLifetimeScope()); }