Example #1
0
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                IPipeline pipeline;
                context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                switch (type)
                {
                case "parallel.linq":
                    pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context));
                    break;

                default:
                    pipeline = new DefaultPipeline(outputController, context);
                    break;
                }

                var provider = process.Output().Provider;

                // 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);

                // transform
                if (!process.ReadOnly)
                {
                    pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                }

                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), 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)));
                    if (provider == "sqlserver")
                    {
                        pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1)));
                    }
                }

                // 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);
        }
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                IPipeline pipeline;
                context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                switch (type)
                {
                case "parallel.linq":
                    pipeline = new ParallelPipeline(new DefaultPipeline(ctx.ResolveNamed <IOutputController>(entity.Key), context));
                    break;

                default:
                    pipeline = new DefaultPipeline(ctx.ResolveNamed <IOutputController>(entity.Key), context);
                    break;
                }

                var provider = process.Output().Provider;

                // extract
                pipeline.Register(ctx.ResolveNamed <IRead>(entity.Key));

                // transform
                pipeline.Register(new SetBatchId(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflBatchId())));
                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), context.GetAllEntityFields()));
                pipeline.Register(TransformFactory.GetTransforms(ctx, process, entity, entity.GetAllFields().Where(f => f.Transforms.Any())));
                pipeline.Register(new SetKey(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflKey())));
                pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));

                if (provider == "sqlserver")
                {
                    pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1)));
                }

                //load
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite))
                    ? ctx.ResolveNamed <IWrite>(entity.Key)
                    : new NullWriter());

                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate))
                    ? ctx.ResolveNamed <IUpdate>(entity.Key)
                    : new NullUpdater());

                return(pipeline);
            }).Named <IPipeline>(entity.Key);
        }
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                IPipeline pipeline;
                context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                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 CancelTransform(context));  may create a problem when canceling without the intention to run full init afterwards
                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);
        }
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                context.Debug(() => string.Format("Registering {0} for entity {1}.", type, entity.Alias));
                var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                var pipeline         = new DefaultPipeline(outputController, context);

                var output = process.Output();

                // extract
                pipeline.Register(ctx.ResolveNamed <IRead>(entity.Key));

                // transform
                if (!process.ReadOnly)
                {
                    pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflBatchId())));
                }

                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), 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)));
                    if (output.Provider == "sqlserver")
                    {
                        pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1)));
                    }
                }

                // 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);
        }
        protected override void Load(ContainerBuilder builder)
        {
            if (_process == null)
            {
                return;
            }

            // Connections
            foreach (var c in _process.Connections.Where(cn => cn.Provider == "lucene"))
            {
                switch (c.Provider)
                {
                case "lucene":
                    // Analyzers
                    builder.Register <Analyzer>(ctx => new KeywordAnalyzer()).Named <Analyzer>(DefaultAnalyzer);
                    foreach (var analyzer in _process.SearchTypes.Where(st => st.Analyzer != string.Empty && st.Analyzer != DefaultAnalyzer).Select(st => st.Analyzer).Distinct())
                    {
                        switch (analyzer)
                        {
                        case "simple":
                            builder.Register <Analyzer>(ctx => new SimpleAnalyzer()).Named <Analyzer>(analyzer);
                            break;

                        case "whitespace":
                            builder.Register <Analyzer>(ctx => new WhitespaceAnalyzer()).Named <Analyzer>(analyzer);
                            break;

                        case "standard":
                            builder.Register <Analyzer>(ctx => new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)).Named <Analyzer>(analyzer);
                            break;

                        default:
                            builder.Register <Analyzer>(ctx => new KeywordAnalyzer()).Named <Analyzer>(analyzer);
                            break;
                        }
                    }

                    // entity index writers
                    foreach (var e in _process.Entities)
                    {
                        // Directory
                        builder.Register(ctx => new DirectoryFactory(Path.Combine(c.Folder, e.Alias))).Named <DirectoryFactory>(e.Key);

                        // Per Field Analyzer
                        builder.Register <Analyzer>(ctx => {
                            var analyzers = new PerFieldAnalyzerWrapper(ctx.ResolveNamed <Analyzer>(DefaultAnalyzer));
                            var context   = ctx.ResolveNamed <OutputContext>(e.Key);
                            foreach (var field in new FieldSearchTypes(context.Process, context.OutputFields))
                            {
                                if (field.SearchType.Name != "none")
                                {
                                    analyzers.AddAnalyzer(field.Alias, ctx.ResolveNamed <Analyzer>(field.SearchType.Analyzer == string.Empty ? DefaultAnalyzer : field.SearchType.Analyzer));
                                }
                            }
                            return(analyzers);
                        }).Named <Analyzer>(e.Key + ReadFrom.Output);

                        builder.Register <Analyzer>(ctx => {
                            var analyzers = new PerFieldAnalyzerWrapper(ctx.ResolveNamed <Analyzer>(DefaultAnalyzer));
                            var context   = ctx.ResolveNamed <InputContext>(e.Key);
                            foreach (var field in new FieldSearchTypes(context.Process, context.InputFields))
                            {
                                if (field.SearchType.Name != "none")
                                {
                                    analyzers.AddAnalyzer(field.Field.Name, ctx.ResolveNamed <Analyzer>(field.SearchType.Analyzer == string.Empty ? DefaultAnalyzer : field.SearchType.Analyzer));
                                }
                            }
                            return(analyzers);
                        }).Named <Analyzer>(e.Key + ReadFrom.Input);

                        // Index Writer Factory
                        builder.Register(ctx => new IndexWriterFactory(ctx.ResolveNamed <DirectoryFactory>(e.Key), ctx.ResolveNamed <Analyzer>(e.Key + ReadFrom.Output))).Named <IndexWriterFactory>(e.Key);

                        // Index Reader Factory
                        builder.Register(ctx => new IndexReaderFactory(ctx.ResolveNamed <DirectoryFactory>(e.Key), ctx.ResolveNamed <IndexWriterFactory>(e.Key))).Named <IndexReaderFactory>(e.Key);

                        // Index Searcher Factory
                        builder.Register(ctx => new SearcherFactory(ctx.ResolveNamed <IndexReaderFactory>(e.Key))).Named <SearcherFactory>(e.Key);
                    }

                    break;
                }
            }

            // entity input
            foreach (var entity in _process.Entities.Where(e => _process.Connections.First(c => c.Name == e.Connection).Provider == "lucene"))
            {
                // INPUT VERSION DETECTOR
                builder.Register <IInputVersionDetector>(ctx => {
                    var input = ctx.ResolveNamed <InputContext>(entity.Key);
                    switch (input.Connection.Provider)
                    {
                    case "lucene":
                        return(new LuceneInputVersionDetector(input, ctx.ResolveNamed <SearcherFactory>(entity.Key)));

                    default:
                        return(new NullVersionDetector());
                    }
                }).Named <IInputVersionDetector>(entity.Key);

                // INPUT READER
                builder.Register <IRead>(ctx => {
                    var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                    var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));

                    switch (input.Connection.Provider)
                    {
                    case "lucene":
                        return(new LuceneReader(input, input.InputFields, ctx.ResolveNamed <SearcherFactory>(entity.Key), ctx.ResolveNamed <Analyzer>(entity.Key + ReadFrom.Input), ctx.ResolveNamed <IndexReaderFactory>(entity.Key), rowFactory, ReadFrom.Input));

                    default:
                        return(new NullReader(input, false));
                    }
                }).Named <IRead>(entity.Key);
            }

            // entity output
            if (_process.Output().Provider == "lucene")
            {
                // PROCESS OUTPUT CONTROLLER
                builder.Register <IOutputController>(ctx => new NullOutputController()).As <IOutputController>();

                // PROCESS INITIALIZER
                builder.Register <IInitializer>(ctx => {
                    var output = ctx.Resolve <OutputContext>();
                    return(new LuceneInitializer(output));
                }).As <IInitializer>();

                foreach (var entity in _process.Entities)
                {
                    // UPDATER
                    builder.Register <IUpdate>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        output.Warn($"{output.Connection.Provider} does not denormalize.");
                        return(new NullMasterUpdater());
                    }).Named <IUpdate>(entity.Key);

                    // OUTPUT
                    builder.Register <IOutputController>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);

                        switch (output.Connection.Provider)
                        {
                        case "lucene":
                            return(new LuceneOutputController(
                                       output,
                                       new NullInitializer(),
                                       ctx.ResolveNamed <IInputVersionDetector>(entity.Key),
                                       new LuceneOutputVersionDetector(output, ctx.ResolveNamed <SearcherFactory>(entity.Key)),
                                       ctx.ResolveNamed <SearcherFactory>(entity.Key),
                                       ctx.ResolveNamed <IndexReaderFactory>(entity.Key)
                                       ));

                        default:
                            return(new NullOutputController());
                        }
                    }).Named <IOutputController>(entity.Key);

                    // WRITER
                    builder.Register <IWrite>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);

                        switch (output.Connection.Provider)
                        {
                        case "lucene":
                            return(new LuceneWriter(output, ctx.ResolveNamed <IndexWriterFactory>(entity.Key), ctx.ResolveNamed <SearcherFactory>(entity.Key)));

                        default:
                            return(new NullWriter(output));
                        }
                    }).Named <IWrite>(entity.Key);

                    // DELETE HANDLER
                    if (entity.Delete)
                    {
                        builder.Register <IEntityDeleteHandler>(ctx => {
                            var context      = ctx.ResolveNamed <IContext>(entity.Key);
                            var inputContext = ctx.ResolveNamed <InputContext>(entity.Key);
                            var rowFactory   = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", inputContext.RowCapacity));
                            IRead input      = new NullReader(context);
                            var primaryKey   = entity.GetPrimaryKey();

                            switch (inputContext.Connection.Provider)
                            {
                            case "lucene":
                                input = new LuceneReader(
                                    inputContext,
                                    primaryKey,
                                    ctx.ResolveNamed <SearcherFactory>(entity.Key),
                                    ctx.ResolveNamed <Analyzer>(entity.Key + ReadFrom.Input),
                                    ctx.ResolveNamed <IndexReaderFactory>(entity.Key),
                                    rowFactory,
                                    ReadFrom.Input);
                                break;
                            }

                            IRead output         = new NullReader(context);
                            IDelete deleter      = new NullDeleter(context);
                            var outputConnection = _process.Output();
                            var outputContext    = ctx.ResolveNamed <OutputContext>(entity.Key);

                            switch (outputConnection.Provider)
                            {
                            case "lucene":
                                output = new LuceneReader(
                                    outputContext,
                                    primaryKey,
                                    ctx.ResolveNamed <SearcherFactory>(entity.Key),
                                    ctx.ResolveNamed <Analyzer>(entity.Key + ReadFrom.Output),
                                    ctx.ResolveNamed <IndexReaderFactory>(entity.Key),
                                    rowFactory,
                                    ReadFrom.Output
                                    );
                                //TODO: need LuceneUpdater (update TflDeleted to true)
                                break;
                            }

                            var handler = new DefaultDeleteHandler(context, input, output, deleter);

                            // since the primary keys from the input may have been transformed into the output, you have to transform before comparing
                            // feels a lot like entity pipeline on just the primary keys... may look at consolidating
                            handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray()));
                            handler.Register(TransformFactory.GetTransforms(ctx, _process, entity, primaryKey));
                            handler.Register(new StringTruncateTransfom(context, primaryKey));

                            return(new ParallelDeleteHandler(handler));
                        }).Named <IEntityDeleteHandler>(entity.Key);
                    }
                }
            }
        }
Example #6
0
        protected override void Load(ContainerBuilder builder)
        {
            if (_process == null)
            {
                return;
            }

            var calc   = _process.ToCalculatedFieldsProcess();
            var entity = calc.Entities.First();

            // I need a process keyed pipeline
            builder.Register(ctx => {
                var context       = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity);
                var outputContext = new OutputContext(context, new Incrementer(context));

                IPipeline pipeline;
                context.Debug(() => $"Registering {_process.Pipeline} pipeline.");
                var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController();
                switch (_process.Pipeline)
                {
                case "parallel.linq":
                    pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context));
                    break;

                default:
                    pipeline = new DefaultPipeline(outputController, context);
                    break;
                }

                // 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 DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields));
                pipeline.Register(TransformFactory.GetTransforms(ctx, calc, entity, entity.CalculatedFields));
                pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity)));

                // register input and output
                switch (outputContext.Connection.Provider)
                {
                case "sqlserver":
                    pipeline.Register(ctx.Resolve <IRead>());
                    pipeline.Register(ctx.Resolve <IWrite>());
                    pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), new DateTime(1753, 1, 1)));
                    break;

                case "mysql":
                case "postgresql":
                case "sqlce":
                case "sqlite":
                    pipeline.Register(ctx.Resolve <IRead>());
                    pipeline.Register(ctx.Resolve <IWrite>());
                    break;

                default:
                    pipeline.Register(new NullReader(context));
                    pipeline.Register(new NullWriter(context));
                    break;
                }

                return(pipeline);
            }).As <IPipeline>();
        }
        protected override void Load(ContainerBuilder builder)
        {
            if (_process == null)
            {
                return;
            }

            //CONNECTIONS
            foreach (var connection in _process.Connections.Where(c => c.Provider.In("elasticsearch")))
            {
                connection.Url = connection.BuildElasticUrl();

                builder.Register <IConnectionPool>(ctx => new SingleNodeConnectionPool(new Uri(connection.Url))).Named <IConnectionPool>(connection.Key);

                // Elasticsearch.Net
                builder.Register(ctx => {
                    var settings = new ConnectionConfiguration(ctx.ResolveNamed <IConnectionPool>(connection.Key));
                    if (_process.Mode != "init" && connection.RequestTimeout >= 0)
                    {
                        settings.RequestTimeout(new TimeSpan(0, 0, 0, connection.RequestTimeout * 1000));
                    }
                    if (connection.Timeout > 0)
                    {
                        settings.PingTimeout(new TimeSpan(0, 0, connection.Timeout));
                    }
                    return(new ElasticLowLevelClient(settings));
                }).Named <IElasticLowLevelClient>(connection.Key);

                // Process-Level Schema Reader
                builder.Register <ISchemaReader>(ctx => new ElasticSchemaReader(ctx.ResolveNamed <IConnectionContext>(connection.Key), ctx.ResolveNamed <IElasticLowLevelClient>(connection.Key))).Named <ISchemaReader>(connection.Key);

                // Entity Level Schema Readers
                foreach (var entity in _process.Entities.Where(e => e.Connection == connection.Name))
                {
                    builder.Register <ISchemaReader>(ctx => new ElasticSchemaReader(ctx.ResolveNamed <IConnectionContext>(entity.Key), ctx.ResolveNamed <IElasticLowLevelClient>(connection.Key))).Named <ISchemaReader>(entity.Key);
                }
            }

            // Entity Input
            foreach (var entity in _process.Entities.Where(e => _process.Connections.First(c => c.Name == e.Connection).Provider == "elasticsearch"))
            {
                builder.Register <IInputVersionDetector>(ctx => {
                    var input = ctx.ResolveNamed <InputContext>(entity.Key);
                    switch (input.Connection.Provider)
                    {
                    case "elasticsearch":
                        return(new ElasticInputVersionDetector(input, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key)));

                    default:
                        return(new NullVersionDetector());
                    }
                }).Named <IInputVersionDetector>(entity.Key);

                // INPUT READER
                builder.Register <IRead>(ctx => {
                    var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                    var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));

                    switch (input.Connection.Provider)
                    {
                    case "elasticsearch":
                        return(new ElasticReader(input, input.InputFields, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key), rowFactory, ReadFrom.Input));

                    default:
                        return(new NullReader(input, false));
                    }
                }).Named <IRead>(entity.Key);
            }

            // Entity Output
            if (_process.Output().Provider == "elasticsearch")
            {
                // PROCESS OUTPUT CONTROLLER
                builder.Register <IOutputController>(ctx => new NullOutputController()).As <IOutputController>();

                // PROCESS INITIALIZER
                builder.Register <IInitializer>(ctx => {
                    var output = ctx.Resolve <OutputContext>();
                    return(new ElasticInitializer(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)));
                }).As <IInitializer>();

                foreach (var entity in _process.Entities)
                {
                    // UPDATER
                    builder.Register <IUpdate>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        output.Warn($"{output.Connection.Provider} does not denormalize.");
                        return(new NullMasterUpdater());
                    }).Named <IUpdate>(entity.Key);

                    // OUTPUT
                    builder.Register <IOutputController>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        switch (output.Connection.Provider)
                        {
                        case "elasticsearch":
                            var initializer = _process.Mode == "init" ? (IAction) new ElasticEntityInitializer(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)) : new NullInitializer();
                            return(new ElasticOutputController(
                                       output,
                                       initializer,
                                       ctx.ResolveNamed <IInputVersionDetector>(entity.Key),
                                       new ElasticOutputVersionDetector(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)),
                                       ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)
                                       ));

                        default:
                            return(new NullOutputController());
                        }
                    }).Named <IOutputController>(entity.Key);

                    // WRITER
                    builder.Register <IWrite>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);

                        switch (output.Connection.Provider)
                        {
                        case "elasticsearch":
                            return(new ElasticWriter(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)));

                        default:
                            return(new NullWriter(output));
                        }
                    }).Named <IWrite>(entity.Key);

                    // DELETE HANDLER
                    if (entity.Delete)
                    {
                        builder.Register <IEntityDeleteHandler>(ctx => {
                            var context      = ctx.ResolveNamed <IContext>(entity.Key);
                            var inputContext = ctx.ResolveNamed <InputContext>(entity.Key);
                            var rowFactory   = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", inputContext.RowCapacity));
                            IRead input      = new NullReader(context);
                            var primaryKey   = entity.GetPrimaryKey();

                            switch (inputContext.Connection.Provider)
                            {
                            case "elasticsearch":
                                input = new ElasticReader(
                                    inputContext,
                                    primaryKey,
                                    ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key),
                                    rowFactory,
                                    ReadFrom.Input
                                    );
                                break;
                            }

                            IRead output         = new NullReader(context);
                            IDelete deleter      = new NullDeleter(context);
                            var outputConnection = _process.Output();
                            var outputContext    = ctx.ResolveNamed <OutputContext>(entity.Key);

                            switch (outputConnection.Provider)
                            {
                            case "elasticsearch":
                                output = new ElasticReader(
                                    outputContext,
                                    primaryKey,
                                    ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key),
                                    rowFactory,
                                    ReadFrom.Output
                                    );
                                deleter = new ElasticPartialUpdater(
                                    outputContext,
                                    new[] { context.Entity.TflDeleted() },
                                    ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key)
                                    );
                                break;
                            }

                            var handler = new DefaultDeleteHandler(context, input, output, deleter);

                            // since the primary keys from the input may have been transformed into the output, you have to transform before comparing
                            // feels a lot like entity pipeline on just the primary keys... may look at consolidating
                            handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray()));
                            handler.Register(TransformFactory.GetTransforms(ctx, _process, entity, primaryKey));
                            handler.Register(new StringTruncateTransfom(context, primaryKey));

                            return(new ParallelDeleteHandler(handler));
                        }).Named <IEntityDeleteHandler>(entity.Key);
                    }
                }
            }
        }
Example #8
0
        public void Build()
        {
            //MAPS
            foreach (var map in _process.Maps.Where(m => m.Connection != string.Empty && m.Query != string.Empty))
            {
                var connection = _process.Connections.First(c => c.Name == map.Connection);
                if (connection != null && connection.Provider == "elasticsearch")
                {
                    _builder.Register <IMapReader>(ctx => new DefaultMapReader()).Named <IMapReader>(map.Name);
                }
            }

            //CONNECTIONS
            foreach (var connection in _process.Connections.Where(c => c.Provider == "elasticsearch"))
            {
                if (connection.Servers.Any(s => s.Url != "None"))
                {
                    var uris = new List <Uri>();
                    foreach (var server in connection.Servers.Where(s => s.Url != "None"))
                    {
                        server.Url = server.GetElasticUrl();
                        uris.Add(new Uri(server.Url));
                    }
                    // for now, just use static connection pool, there are 2 other types...
                    _builder.Register <IConnectionPool>(ctx => new StaticConnectionPool(uris)).Named <IConnectionPool>(connection.Key);
                }
                else
                {
                    connection.Url = connection.GetElasticUrl();
                    _builder.Register <IConnectionPool>(ctx => new SingleNodeConnectionPool(new Uri(connection.Url))).Named <IConnectionPool>(connection.Key);
                }

                // Elasticsearch.Net
                _builder.Register(ctx => {
                    var settings = new ConnectionConfiguration(ctx.ResolveNamed <IConnectionPool>(connection.Key));
                    if (!string.IsNullOrEmpty(connection.User))
                    {
                        settings.BasicAuthentication(connection.User, connection.Password);
                    }
                    if (_process.Mode != "init" && connection.RequestTimeout >= 0)
                    {
                        settings.RequestTimeout(new TimeSpan(0, 0, 0, connection.RequestTimeout * 1000));
                    }
                    if (connection.Timeout > 0)
                    {
                        settings.PingTimeout(new TimeSpan(0, 0, connection.Timeout));
                    }
                    return(new ElasticLowLevelClient(settings));
                }).Named <IElasticLowLevelClient>(connection.Key);

                // Process-Level Schema Reader
                _builder.Register <ISchemaReader>(ctx => new ElasticSchemaReader(ctx.ResolveNamed <IConnectionContext>(connection.Key), ctx.ResolveNamed <IElasticLowLevelClient>(connection.Key))).Named <ISchemaReader>(connection.Key);

                // Entity Level Schema Readers
                foreach (var entity in _process.Entities.Where(e => e.Input == connection.Name))
                {
                    _builder.Register <ISchemaReader>(ctx => new ElasticSchemaReader(ctx.ResolveNamed <IConnectionContext>(entity.Key), ctx.ResolveNamed <IElasticLowLevelClient>(connection.Key))).Named <ISchemaReader>(entity.Key);
                }
            }

            // Entity Input
            foreach (var entity in _process.Entities.Where(e => _process.Connections.First(c => c.Name == e.Input).Provider == "elasticsearch"))
            {
                _builder.Register <IInputProvider>(ctx => {
                    var input = ctx.ResolveNamed <InputContext>(entity.Key);
                    return(new ElasticInputProvider(input, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key)));
                }).Named <IInputProvider>(entity.Key);

                // INPUT READER
                _builder.Register <IRead>(ctx => {
                    var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                    var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));

                    if (entity.Query == string.Empty)
                    {
                        return(new ElasticReader(input, input.InputFields, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key), rowFactory, ReadFrom.Input));
                    }
                    return(new ElasticQueryReader(input, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key), rowFactory));
                }).Named <IRead>(entity.Key);
            }

            // Entity Output
            if (_process.GetOutputConnection().Provider == "elasticsearch")
            {
                // PROCESS OUTPUT CONTROLLER
                _builder.Register <IOutputController>(ctx => new NullOutputController()).As <IOutputController>();

                // PROCESS INITIALIZER
                _builder.Register <IInitializer>(ctx => {
                    var output = ctx.Resolve <OutputContext>();
                    return(new ElasticInitializer(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)));
                }).As <IInitializer>();

                foreach (var entity in _process.Entities)
                {
                    // UPDATER
                    _builder.Register <IUpdate>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        output.Debug(() => $"{output.Connection.Provider} does not denormalize.");
                        return(new NullMasterUpdater());
                    }).Named <IUpdate>(entity.Key);

                    // OUTPUT
                    _builder.Register <IOutputController>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        switch (output.Connection.Provider)
                        {
                        case "elasticsearch":
                            var initializer = _process.Mode == "init" ? (IAction) new ElasticEntityInitializer(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)) : new NullInitializer();
                            return(new ElasticOutputController(
                                       output,
                                       initializer,
                                       ctx.ResolveNamed <IInputProvider>(entity.Key),
                                       new ElasticOutputProvider(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)),
                                       ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)
                                       ));

                        default:
                            return(new NullOutputController());
                        }
                    }).Named <IOutputController>(entity.Key);

                    // WRITER
                    _builder.Register <IWrite>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);

                        switch (output.Connection.Provider)
                        {
                        case "elasticsearch":
                            return(new ElasticWriter(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)));

                        default:
                            return(new NullWriter(output));
                        }
                    }).Named <IWrite>(entity.Key);

                    // DELETE HANDLER
                    if (entity.Delete)
                    {
                        _builder.Register <IEntityDeleteHandler>(ctx => {
                            var context      = ctx.ResolveNamed <IContext>(entity.Key);
                            var inputContext = ctx.ResolveNamed <InputContext>(entity.Key);
                            var rowFactory   = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", inputContext.RowCapacity));
                            IRead input      = new NullReader(context);
                            var primaryKey   = entity.GetPrimaryKey();

                            switch (inputContext.Connection.Provider)
                            {
                            case "elasticsearch":
                                input = new ElasticReader(
                                    inputContext,
                                    primaryKey,
                                    ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key),
                                    rowFactory,
                                    ReadFrom.Input
                                    );
                                break;
                            }

                            IRead output         = new NullReader(context);
                            IDelete deleter      = new NullDeleter(context);
                            var outputConnection = _process.GetOutputConnection();
                            var outputContext    = ctx.ResolveNamed <OutputContext>(entity.Key);

                            switch (outputConnection.Provider)
                            {
                            case "elasticsearch":
                                output = new ElasticReader(
                                    outputContext,
                                    primaryKey,
                                    ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key),
                                    rowFactory,
                                    ReadFrom.Output
                                    );
                                deleter = new ElasticPartialUpdater(
                                    outputContext,
                                    new[] { context.Entity.TflDeleted() },
                                    ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key)
                                    );
                                break;
                            }

                            var handler = new DefaultDeleteHandler(context, input, output, deleter);

                            // since the primary keys from the input may have been transformed into the output, you have to transform before comparing
                            // feels a lot like entity pipeline on just the primary keys... may look at consolidating
                            handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray()));
                            handler.Register(TransformFactory.GetTransforms(ctx, context, primaryKey));
                            handler.Register(new StringTruncateTransfom(context, primaryKey));

                            return(handler);
                        }).Named <IEntityDeleteHandler>(entity.Key);
                    }
                }
            }
        }
Example #9
0
        protected override void Load(ContainerBuilder builder)
        {
            if (_process == null)
            {
                return;
            }

            // connections
            foreach (var connection in _process.Connections.Where(c => c.Provider.In(_ado)))
            {
                // Connection Factory
                builder.Register <IConnectionFactory>(ctx => {
                    switch (connection.Provider)
                    {
                    case "sqlserver":
                        return(new SqlServerConnectionFactory(connection));

                    case "mysql":
                        return(new MySqlConnectionFactory(connection));

                    case "postgresql":
                        return(new PostgreSqlConnectionFactory(connection));

                    case "sqlite":
                        return(new SqLiteConnectionFactory(connection));

                    default:
                        return(new NullConnectionFactory());
                    }
                }).Named <IConnectionFactory>(connection.Key).InstancePerLifetimeScope();

                // Schema Reader
                builder.Register <ISchemaReader>(ctx => {
                    var factory = ctx.ResolveNamed <IConnectionFactory>(connection.Key);
                    return(new AdoSchemaReader(ctx.ResolveNamed <IConnectionContext>(connection.Key), factory));
                }).Named <ISchemaReader>(connection.Key);
            }

            //ISchemaReader
            //IOutputController
            //IRead (Process for Calculated Columns)
            //IWrite (Process for Calculated Columns)
            //IInitializer (Process)

            // Per Entity
            // IInputVersionDetector
            // IRead (Input, per Entity)
            // IOutputController
            // -- ITakeAndReturnRows (for matching)
            // -- IWriteMasterUpdateQuery (for updating)
            // IUpdate
            // IWrite
            // IEntityDeleteHandler

            // entitiy input
            foreach (var entity in _process.Entities.Where(e => _process.Connections.First(c => c.Name == e.Connection).Provider.In(_ado)))
            {
                // INPUT READER
                builder.Register <IRead>(ctx => {
                    var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                    var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));

                    switch (input.Connection.Provider)
                    {
                    case "mysql":
                    case "postgresql":
                    case "sqlite":
                    case "sqlserver":
                        return(new AdoInputReader(
                                   input,
                                   input.InputFields,
                                   ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key),
                                   rowFactory
                                   ));

                    default:
                        return(new NullReader(input, false));
                    }
                }).Named <IRead>(entity.Key);

                // INPUT VERSION DETECTOR
                builder.Register <IInputVersionDetector>(ctx => {
                    var input = ctx.ResolveNamed <InputContext>(entity.Key);
                    switch (input.Connection.Provider)
                    {
                    case "mysql":
                    case "postgresql":
                    case "sqlite":
                    case "sqlserver":
                        return(new AdoInputVersionDetector(input, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key)));

                    default:
                        return(new NullVersionDetector());
                    }
                }).Named <IInputVersionDetector>(entity.Key);
            }

            // entity output
            if (_process.Output().Provider.In(_ado))
            {
                var calc = _process.ToCalculatedFieldsProcess();

                // PROCESS OUTPUT CONTROLLER
                builder.Register <IOutputController>(ctx => {
                    var output = ctx.Resolve <OutputContext>();
                    if (_process.Mode != "init")
                    {
                        return(new NullOutputController());
                    }

                    switch (output.Connection.Provider)
                    {
                    case "mysql":
                    case "postgresql":
                    case "sqlite":
                    case "sqlserver":
                        return(new AdoStarController(output, new AdoStarViewCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))));

                    default:
                        return(new NullOutputController());
                    }
                }).As <IOutputController>();

                // PROCESS CALCULATED READER
                builder.Register <IRead>(ctx => {
                    var calcContext   = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First());
                    var outputContext = new OutputContext(calcContext, new Incrementer(calcContext));
                    var cf            = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key);
                    var capacity      = outputContext.Entity.Fields.Count + outputContext.Entity.CalculatedFields.Count;
                    var rowFactory    = new RowFactory(capacity, false, false);
                    return(new AdoStarParametersReader(outputContext, _process, cf, rowFactory));
                }).As <IRead>();

                // PROCESS CALCULATED FIELD WRITER
                builder.Register <IWrite>(ctx => {
                    var calcContext   = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First());
                    var outputContext = new OutputContext(calcContext, new Incrementer(calcContext));
                    var cf            = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key);
                    return(new AdoCalculatedFieldUpdater(outputContext, _process, cf));
                }).As <IWrite>();

                // PROCESS INITIALIZER
                builder.Register <IInitializer>(ctx => {
                    var output = ctx.Resolve <OutputContext>();
                    return(new AdoInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)));
                }).As <IInitializer>();

                // ENTITIES
                foreach (var entity in _process.Entities)
                {
                    // ENTITY OUTPUT CONTROLLER
                    builder.Register <IOutputController>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);

                        switch (output.Connection.Provider)
                        {
                        case "mysql":
                        case "postgresql":
                        case "sqlite":
                        case "sqlserver":
                            var initializer = _process.Mode == "init" ? (IAction) new AdoEntityInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) : new NullInitializer();
                            return(new AdoOutputController(
                                       output,
                                       initializer,
                                       ctx.ResolveNamed <IInputVersionDetector>(entity.Key),
                                       new AdoOutputVersionDetector(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)),
                                       ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)
                                       ));

                        default:
                            return(new NullOutputController());
                        }
                    }).Named <IOutputController>(entity.Key);

                    // OUTPUT ROW MATCHER
                    builder.Register(ctx => {
                        var output     = ctx.ResolveNamed <OutputContext>(entity.Key);
                        var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", output.GetAllEntityFields().Count()));
                        var cf         = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key);
                        switch (output.Connection.Provider)
                        {
                        case "sqlite":
                            return(new TypedEntityMatchingKeysReader(new AdoEntityMatchingKeysReader(output, cf, rowFactory), output));

                        default:
                            return((ITakeAndReturnRows) new AdoEntityMatchingKeysReader(output, cf, rowFactory));
                        }
                    }).Named <ITakeAndReturnRows>(entity.Key);

                    // MASTER UPDATE QUERY
                    builder.Register <IWriteMasterUpdateQuery>(ctx => {
                        var output  = ctx.ResolveNamed <OutputContext>(entity.Key);
                        var factory = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key);
                        switch (output.Connection.Provider)
                        {
                        case "mysql":
                            return(new MySqlUpdateMasterKeysQueryWriter(output, factory));

                        case "postgresql":
                            return(new PostgreSqlUpdateMasterKeysQueryWriter(output, factory));

                        default:
                            return(new SqlServerUpdateMasterKeysQueryWriter(output, factory));
                        }
                    }).Named <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys");

                    // UPDATER
                    builder.Register <IUpdate>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        switch (output.Connection.Provider)
                        {
                        case "mysql":
                        case "postgresql":
                        case "sqlserver":
                            return(new AdoMasterUpdater(
                                       output,
                                       ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key),
                                       ctx.ResolveNamed <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys")
                                       ));

                        case "sqlite":
                            return(new AdoTwoPartMasterUpdater(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)));

                        default:
                            return(new NullMasterUpdater());
                        }
                    }).Named <IUpdate>(entity.Key);

                    // WRITER
                    builder.Register <IWrite>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);

                        switch (output.Connection.Provider)
                        {
                        case "sqlserver":
                            return(new SqlServerWriter(
                                       output,
                                       ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key),
                                       ctx.ResolveNamed <ITakeAndReturnRows>(entity.Key),
                                       new AdoEntityUpdater(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))
                                       ));

                        case "mysql":
                        case "postgresql":
                        case "sqlite":
                            var cf = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key);
                            return(new AdoEntityWriter(
                                       output,
                                       ctx.ResolveNamed <ITakeAndReturnRows>(entity.Key),
                                       new AdoEntityInserter(output, cf),
                                       new AdoEntityUpdater(output, cf)
                                       ));

                        default:
                            return(new NullWriter(output));
                        }
                    }).Named <IWrite>(entity.Key);


                    // DELETE HANDLER
                    if (entity.Delete)
                    {
                        builder.Register <IEntityDeleteHandler>(ctx => {
                            var context      = ctx.ResolveNamed <IContext>(entity.Key);
                            var inputContext = ctx.ResolveNamed <InputContext>(entity.Key);
                            var rowCapacity  = inputContext.Entity.GetPrimaryKey().Count();
                            var rowFactory   = new RowFactory(rowCapacity, false, true);
                            IRead input      = new NullReader(context);
                            var primaryKey   = entity.GetPrimaryKey();

                            switch (inputContext.Connection.Provider)
                            {
                            case "mysql":
                            case "postgresql":
                            case "sqlite":
                            case "sqlserver":
                                input = new AdoReader(
                                    inputContext,
                                    primaryKey,
                                    ctx.ResolveNamed <IConnectionFactory>(inputContext.Connection.Key),
                                    rowFactory,
                                    ReadFrom.Input
                                    );
                                break;
                            }

                            IRead output         = new NullReader(context);
                            IDelete deleter      = new NullDeleter(context);
                            var outputConnection = _process.Output();
                            var outputContext    = ctx.ResolveNamed <OutputContext>(entity.Key);

                            switch (outputConnection.Provider)
                            {
                            case "mysql":
                            case "postgresql":
                            case "sqlite":
                            case "sqlserver":
                                var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key);
                                output  = new AdoReader(context, entity.GetPrimaryKey(), ocf, rowFactory, ReadFrom.Output);
                                deleter = new AdoDeleter(outputContext, ocf);
                                break;
                            }

                            var handler = new DefaultDeleteHandler(context, input, output, deleter);

                            // since the primary keys from the input may have been transformed into the output, you have to transform before comparing
                            // feels a lot like entity pipeline on just the primary keys... may look at consolidating
                            handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray()));
                            handler.Register(TransformFactory.GetTransforms(ctx, _process, entity, primaryKey));
                            handler.Register(new StringTruncateTransfom(context, primaryKey));

                            return(new ParallelDeleteHandler(handler));
                        }).Named <IEntityDeleteHandler>(entity.Key);
                    }
                }
            }
        }
Example #10
0
        protected override void Load(ContainerBuilder builder)
        {
            if (_process == null)
            {
                return;
            }

            // connections
            foreach (var connection in _process.Connections.Where(c => _ado.Contains(c.Provider)))
            {
                var cn = connection;
                // Connection Factory
                builder.Register <IConnectionFactory>(ctx => {
                    switch (cn.Provider)
                    {
                    case "sqlserver":
                        return(new SqlServerConnectionFactory(cn));

                    default:
                        return(new NullConnectionFactory());
                    }
                }).Named <IConnectionFactory>(connection.Key).InstancePerLifetimeScope();

                // Schema Reader
                builder.Register <ISchemaReader>(ctx => {
                    var factory = ctx.ResolveNamed <IConnectionFactory>(cn.Key);
                    return(new AdoSchemaReader(ctx.ResolveNamed <IConnectionContext>(cn.Key), factory));
                }).Named <ISchemaReader>(connection.Key);
            }

            //ISchemaReader
            //IOutputController
            //IRead (Process for Calculated Columns)
            //IWrite (Process for Calculated Columns)
            //IInitializer (Process)

            // Per Entity
            // IInputVersionDetector
            // IRead (Input, per Entity)
            // IOutputController
            // -- IBatchReader (for matching)
            // -- IWriteMasterUpdateQuery (for updating)
            // IUpdate
            // IWrite
            // IEntityDeleteHandler

            // entitiy input
            foreach (var entity in _process.Entities.Where(e => _ado.Contains(_process.Connections.First(c => c.Name == e.Connection).Provider)))
            {
                // INPUT READER
                builder.Register(ctx => {
                    var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                    var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));
                    IRead dataReader;
                    switch (input.Connection.Provider)
                    {
                    case "mysql":
                    case "sqlserver":
                        dataReader = new AdoInputReader(
                            input,
                            input.InputFields,
                            ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key),
                            rowFactory
                            );
                        break;

                    default:
                        dataReader = new NullReader(input, false);
                        break;
                    }

                    // "form" mode support if filter on primary key exists
                    if (_process.Mode == "form" && entity.GetPrimaryKey().Any() && entity.GetPrimaryKey().All(f => entity.Filter.Any(i => i.Field == f.Alias || i.Field == f.Name)))
                    {
                        if (entity.GetPrimaryKey().All(pk => entity.Filter.First(i => i.Field == pk.Alias || i.Field == pk.Name).Value == (pk.Default == Constants.DefaultSetting ? Constants.StringDefaults()[pk.Type] : pk.Default)))
                        {
                            // primary key is default, don't read from database
                            return(new ParameterRowReader(input, new DefaultRowReader(input, rowFactory)));
                        }

                        // read from database and update with parameters, otherwise just return the data reader
                        if (HttpContext.Current.Request.HttpMethod == "POST")
                        {
                            return(new ParameterRowReader(input, dataReader, rowFactory));
                        }
                    }

                    return(dataReader);
                }).Named <IRead>(entity.Key);

                // INPUT VERSION DETECTOR
                builder.Register <IInputProvider>(ctx => {
                    var input = ctx.ResolveNamed <InputContext>(entity.Key);
                    switch (input.Connection.Provider)
                    {
                    case "mysql":
                    case "sqlserver":
                        return(new AdoInputProvider(input, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key)));

                    default:
                        return(new NullInputProvider());
                    }
                }).Named <IInputProvider>(entity.Key);
            }

            // entity output
            if (_ado.Contains(_process.Output().Provider))
            {
                var calc = _process.ToCalculatedFieldsProcess();

                // PROCESS OUTPUT CONTROLLER
                builder.Register <IOutputController>(ctx => {
                    var output = ctx.Resolve <OutputContext>();
                    if (_process.Mode != "init")
                    {
                        return(new NullOutputController());
                    }

                    switch (output.Connection.Provider)
                    {
                    case "mysql":
                    case "sqlserver":
                        var actions = new List <IAction> {
                            new AdoStarViewCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))
                        };
                        if (_process.Flatten)
                        {
                            actions.Add(new AdoFlatTableCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)));
                        }
                        return(new AdoStarController(output, actions));

                    default:
                        return(new NullOutputController());
                    }
                }).As <IOutputController>();

                // PROCESS CALCULATED READER
                builder.Register <IRead>(ctx => {
                    var calcContext   = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First());
                    var outputContext = new OutputContext(calcContext);
                    var cf            = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key);
                    var capacity      = outputContext.Entity.Fields.Count + outputContext.Entity.CalculatedFields.Count;
                    var rowFactory    = new RowFactory(capacity, false, false);
                    return(new AdoStarParametersReader(outputContext, _process, cf, rowFactory));
                }).As <IRead>();

                // PROCESS CALCULATED FIELD WRITER
                builder.Register <IWrite>(ctx => {
                    var calcContext   = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First());
                    var outputContext = new OutputContext(calcContext);
                    var cf            = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key);
                    return(new AdoCalculatedFieldUpdater(outputContext, _process, cf));
                }).As <IWrite>();

                // PROCESS INITIALIZER
                builder.Register <IInitializer>(ctx => {
                    var output = ctx.Resolve <OutputContext>();
                    return(new AdoInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)));
                }).As <IInitializer>();

                // ENTITIES
                foreach (var e in _process.Entities)
                {
                    var entity = e;

                    // WRITER
                    builder.Register <IWrite>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        var cf     = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key);

                        switch (output.Connection.Provider)
                        {
                        case "sqlserver":
                            return(new SqlServerWriter(
                                       output,
                                       cf,
                                       ctx.ResolveNamed <IBatchReader>(entity.Key),
                                       new AdoEntityUpdater(output, cf)
                                       ));

                        case "mysql":
                            return(new AdoEntityWriter(
                                       output,
                                       ctx.ResolveNamed <IBatchReader>(entity.Key),
                                       new AdoEntityInserter(output, cf),
                                       entity.Update ? (IWrite) new AdoEntityUpdater(output, cf) : new NullWriter(output)
                                       ));

                        default:
                            return(new NullWriter(output));
                        }
                    }).Named <IWrite>(entity.Key);

                    builder.Register <IOutputProvider>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        return(new AdoOutputProvider(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key), ctx.ResolveNamed <IWrite>(entity.Key)));
                    }).Named <IOutputProvider>(entity.Key);

                    // ENTITY OUTPUT CONTROLLER
                    builder.Register <IOutputController>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);

                        switch (output.Connection.Provider)
                        {
                        case "mysql":
                        case "sqlserver":
                            var initializer = _process.Mode == "init" ? (IAction) new AdoEntityInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) : new NullInitializer();
                            return(new AdoOutputController(
                                       output,
                                       initializer,
                                       ctx.ResolveNamed <IInputProvider>(entity.Key),
                                       ctx.ResolveNamed <IOutputProvider>(entity.Key),
                                       ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)
                                       ));

                        default:
                            return(new NullOutputController());
                        }
                    }).Named <IOutputController>(entity.Key);

                    // OUTPUT ROW MATCHER
                    builder.Register <IBatchReader>(ctx => {
                        if (!entity.Update)
                        {
                            return(new NullBatchReader());
                        }
                        var output     = ctx.ResolveNamed <OutputContext>(entity.Key);
                        var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", output.GetAllEntityFields().Count()));
                        var cf         = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key);
                        return(new AdoEntityMatchingKeysReader(output, cf, rowFactory));
                    }).Named <IBatchReader>(entity.Key);

                    // MASTER UPDATE QUERY
                    builder.Register <IWriteMasterUpdateQuery>(ctx => {
                        var output  = ctx.ResolveNamed <OutputContext>(entity.Key);
                        var factory = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key);
                        return(new SqlServerUpdateMasterKeysQueryWriter(output, factory));
                    }).Named <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys");

                    // MASTER UPDATER
                    builder.Register <IUpdate>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        switch (output.Connection.Provider)
                        {
                        case "mysql":
                        case "postgresql":
                        case "sqlserver":
                            return(new AdoMasterUpdater(
                                       output,
                                       ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key),
                                       ctx.ResolveNamed <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys")
                                       ));

                        case "sqlite":
                        case "sqlce":
                            return(new AdoTwoPartMasterUpdater(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)));

                        default:
                            return(new NullMasterUpdater());
                        }
                    }).Named <IUpdate>(entity.Key);

                    // DELETE HANDLER
                    if (entity.Delete)
                    {
                        // register input keys and hashcode reader if necessary
                        var provider = _process.Connections.First(c => c.Name == entity.Connection).Provider;
                        if (_ado.Contains(provider))
                        {
                            builder.Register <IReadInputKeysAndHashCodes>(ctx => {
                                var inputContext = ctx.ResolveNamed <InputContext>(entity.Key);
                                var rowCapacity  = inputContext.Entity.GetPrimaryKey().Count();
                                var rowFactory   = new RowFactory(rowCapacity, false, true);
                                return(new AdoReader(
                                           inputContext,
                                           entity.GetPrimaryKey(),
                                           ctx.ResolveNamed <IConnectionFactory>(inputContext.Connection.Key),
                                           rowFactory,
                                           ReadFrom.Input
                                           ));
                            }).Named <IReadInputKeysAndHashCodes>(entity.Key);
                        }

                        // register output keys and hash code reader if necessary
                        builder.Register <IReadOutputKeysAndHashCodes>((ctx => {
                            var context = ctx.ResolveNamed <OutputContext>(entity.Key);
                            var rowCapacity = context.Entity.GetPrimaryKey().Count();
                            var rowFactory = new RowFactory(rowCapacity, false, true);

                            var outputConnection = _process.Output();
                            switch (outputConnection.Provider)
                            {
                            case "mysql":
                            case "sqlserver":
                                var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key);
                                return(new AdoReader(context, entity.GetPrimaryKey(), ocf, rowFactory, ReadFrom.Output));

                            default:
                                return(new NullReader(context));
                            }
                        })).Named <IReadOutputKeysAndHashCodes>(entity.Key);

                        builder.Register((ctx) => {
                            var outputConnection = _process.Output();
                            var outputContext    = ctx.ResolveNamed <OutputContext>(entity.Key);

                            switch (outputConnection.Provider)
                            {
                            case "mysql":
                            case "sqlserver":
                                var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key);
                                return(new AdoDeleter(outputContext, ocf));

                            default:
                                return(ctx.IsRegisteredWithName <IDelete>(entity.Key) ? ctx.ResolveNamed <IDelete>(entity.Key) : new NullDeleter(outputContext));
                            }
                        }).Named <IDelete>(entity.Key);

                        builder.Register <IEntityDeleteHandler>(ctx => {
                            var context    = ctx.ResolveNamed <IContext>(entity.Key);
                            var primaryKey = entity.GetPrimaryKey().ToArray();

                            var handler = new DefaultDeleteHandler(
                                context,
                                ctx.ResolveNamed <IReadInputKeysAndHashCodes>(entity.Key),
                                ctx.ResolveNamed <IReadOutputKeysAndHashCodes>(entity.Key),
                                ctx.ResolveNamed <IDelete>(entity.Key)
                                );

                            // since the primary keys from the input may have been transformed into the output, you have to transform before comparing
                            // feels a lot like entity pipeline on just the primary keys... may look at consolidating
                            handler.Register(new DefaultTransform(context, primaryKey));
                            handler.Register(TransformFactory.GetTransforms(ctx, context, primaryKey));
                            handler.Register(new StringTruncateTransfom(context, primaryKey));

                            return(new ParallelDeleteHandler(handler));
                        }).Named <IEntityDeleteHandler>(entity.Key);
                    }
                }
            }
        }
Example #11
0
        protected override void Load(ContainerBuilder builder)
        {
            if (!builder.Properties.ContainsKey("Process"))
            {
                return;
            }

            var process = (Process)builder.Properties["Process"];

            // connections
            foreach (var connection in process.Connections.Where(c => c.Provider == Access))
            {
                // Connection Factory
                builder.Register <IConnectionFactory>(ctx => {
                    switch (connection.Provider)
                    {
                    case "access":
                        return(new AccessConnectionFactory(connection));

                    default:
                        return(new NullConnectionFactory());
                    }
                }).Named <IConnectionFactory>(connection.Key).InstancePerLifetimeScope();

                // Schema Reader
                builder.Register <ISchemaReader>(ctx => {
                    var factory = ctx.ResolveNamed <IConnectionFactory>(connection.Key);
                    return(new AdoSchemaReader(ctx.ResolveNamed <IConnectionContext>(connection.Key), factory));
                }).Named <ISchemaReader>(connection.Key);
            }

            // entity input
            foreach (var entity in process.Entities.Where(e => process.Connections.First(c => c.Name == e.Input).Provider == Access))
            {
                // INPUT READER
                builder.Register <IRead>(ctx => {
                    var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                    var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));
                    switch (input.Connection.Provider)
                    {
                    case "access":
                        return(new AdoInputReader(
                                   input,
                                   input.InputFields,
                                   ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key),
                                   rowFactory
                                   ));

                    default:
                        return(new NullReader(input, false));
                    }
                }).Named <IRead>(entity.Key);

                // INPUT VERSION DETECTOR
                builder.Register <IInputProvider>(ctx => {
                    var input = ctx.ResolveNamed <InputContext>(entity.Key);
                    switch (input.Connection.Provider)
                    {
                    case "access":
                        return(new AdoInputProvider(input, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key)));

                    default:
                        return(new NullInputProvider());
                    }
                }).Named <IInputProvider>(entity.Key);
            }

            // entity output
            if (process.GetOutputConnection().Provider == Access)
            {
                var calc = process.ToCalculatedFieldsProcess();

                // PROCESS OUTPUT CONTROLLER
                builder.Register <IOutputController>(ctx => {
                    var output = ctx.Resolve <OutputContext>();
                    if (process.Mode != "init")
                    {
                        return(new NullOutputController());
                    }

                    switch (output.Connection.Provider)
                    {
                    case "access":
                        var actions = new List <IAction> {
                            new AdoStarViewCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))
                        };
                        if (process.Flatten)
                        {
                            actions.Add(new AdoFlatTableCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)));
                        }
                        return(new AdoStarController(output, actions));

                    default:
                        return(new NullOutputController());
                    }
                }).As <IOutputController>();

                // PROCESS CALCULATED READER
                builder.Register <IRead>(ctx => {
                    var calcContext   = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First());
                    var outputContext = new OutputContext(calcContext);
                    var cf            = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key);
                    var capacity      = outputContext.Entity.Fields.Count + outputContext.Entity.CalculatedFields.Count;
                    var rowFactory    = new RowFactory(capacity, false, false);
                    return(new AdoStarParametersReader(outputContext, process, cf, rowFactory));
                }).As <IRead>();

                // PROCESS CALCULATED FIELD WRITER
                builder.Register <IWrite>(ctx => {
                    var calcContext   = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First());
                    var outputContext = new OutputContext(calcContext);
                    var cf            = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key);
                    return(new AdoCalculatedFieldUpdater(outputContext, process, cf));
                }).As <IWrite>();

                // PROCESS INITIALIZER
                builder.Register <IInitializer>(ctx => {
                    var output  = ctx.Resolve <OutputContext>();
                    var adoInit = new AdoInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key));
                    switch (output.Connection.Provider)
                    {
                    case "access":
                        return(new AccessInitializer(adoInit, output));

                    default:
                        return(adoInit);
                    }
                }).As <IInitializer>();

                // ENTITIES
                foreach (var entity in process.Entities)
                {
                    builder.Register <IOutputProvider>(ctx => {
                        IWrite writer;
                        var output     = ctx.ResolveNamed <OutputContext>(entity.Key);
                        var cf         = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key);
                        var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", output.GetAllEntityFields().Count()));

                        // matcher determines what's an update vs. and insert
                        var matcher = entity.Update ? (IBatchReader) new AdoEntityMatchingKeysReader(output, cf, rowFactory) : new NullBatchReader();

                        switch (output.Connection.Provider)
                        {
                        case "access":
                            writer = new AdoEntityWriter(
                                output,
                                matcher,
                                new AdoEntityInserter(output, cf),
                                entity.Update ? (IWrite) new AdoEntityUpdater(output, cf) : new NullWriter(output)
                                );
                            break;

                        default:
                            writer = new NullWriter(output);
                            break;
                        }

                        return(new AdoOutputProvider(output, cf, writer));
                    }).Named <IOutputProvider>(entity.Key);

                    // ENTITY OUTPUT CONTROLLER
                    builder.Register <IOutputController>(ctx => {
                        var output      = ctx.ResolveNamed <OutputContext>(entity.Key);
                        var initializer = process.Mode == "init" ? (IAction) new AdoEntityInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) : new NullInitializer();

                        switch (output.Connection.Provider)
                        {
                        case "access":
                            return(new AdoOutputController(
                                       output,
                                       new AccessInitializer(initializer, output),
                                       ctx.ResolveNamed <IInputProvider>(entity.Key),
                                       ctx.ResolveNamed <IOutputProvider>(entity.Key),
                                       ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)
                                       ));

                        default:
                            return(new NullOutputController());
                        }
                    }).Named <IOutputController>(entity.Key);

                    // MASTER UPDATE QUERY
                    builder.Register <IWriteMasterUpdateQuery>(ctx => {
                        var output  = ctx.ResolveNamed <OutputContext>(entity.Key);
                        var factory = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key);
                        return(new AccessUpdateMasterKeysQueryWriter(output, factory));
                    }).Named <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys");

                    // MASTER UPDATER
                    builder.Register <IUpdate>(ctx => {
                        var output = ctx.ResolveNamed <OutputContext>(entity.Key);
                        switch (output.Connection.Provider)
                        {
                        case "access":
                            return(new AdoMasterUpdater(
                                       output,
                                       ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key),
                                       ctx.ResolveNamed <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys")
                                       ));

                        default:
                            return(new NullMasterUpdater());
                        }
                    }).Named <IUpdate>(entity.Key);

                    // DELETE HANDLER
                    if (entity.Delete)
                    {
                        // register input keys and hashcode reader if necessary
                        builder.Register(ctx => {
                            var inputContext = ctx.ResolveNamed <InputContext>(entity.Key);
                            var rowCapacity  = inputContext.Entity.GetPrimaryKey().Count();
                            var rowFactory   = new RowFactory(rowCapacity, false, true);

                            switch (inputContext.Connection.Provider)
                            {
                            case "access":
                                return(new AdoReader(
                                           inputContext,
                                           entity.GetPrimaryKey(),
                                           ctx.ResolveNamed <IConnectionFactory>(inputContext.Connection.Key),
                                           rowFactory,
                                           ReadFrom.Input
                                           ));

                            default:
                                return(ctx.IsRegisteredWithName <IReadInputKeysAndHashCodes>(entity.Key) ? ctx.ResolveNamed <IReadInputKeysAndHashCodes>(entity.Key) : new NullReader(inputContext));
                            }
                        }).Named <IReadInputKeysAndHashCodes>(entity.Key);

                        // register output keys and hash code reader if necessary
                        builder.Register((ctx => {
                            var context = ctx.ResolveNamed <OutputContext>(entity.Key);
                            var rowCapacity = context.Entity.GetPrimaryKey().Count();
                            var rowFactory = new RowFactory(rowCapacity, false, true);

                            var outputConnection = process.GetOutputConnection();
                            switch (outputConnection.Provider)
                            {
                            case "access":
                                var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key);
                                return(new AdoReader(context, entity.GetPrimaryKey(), ocf, rowFactory, ReadFrom.Output));

                            default:
                                return(ctx.IsRegisteredWithName <IReadOutputKeysAndHashCodes>(entity.Key) ? ctx.ResolveNamed <IReadOutputKeysAndHashCodes>(entity.Key) : new NullReader(context));
                            }
                        })).Named <IReadOutputKeysAndHashCodes>(entity.Key);

                        builder.Register(ctx => {
                            var outputConnection = process.GetOutputConnection();
                            var outputContext    = ctx.ResolveNamed <OutputContext>(entity.Key);

                            switch (outputConnection.Provider)
                            {
                            case "access":
                                var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key);
                                return(new AdoDeleter(outputContext, ocf));

                            default:
                                return(ctx.IsRegisteredWithName <IDelete>(entity.Key) ? ctx.ResolveNamed <IDelete>(entity.Key) : new NullDeleter(outputContext));
                            }
                        }).Named <IDelete>(entity.Key);

                        builder.Register <IEntityDeleteHandler>(ctx => {
                            var context    = ctx.ResolveNamed <IContext>(entity.Key);
                            var primaryKey = entity.GetPrimaryKey();

                            var handler = new DefaultDeleteHandler(
                                context,
                                ctx.ResolveNamed <IReadInputKeysAndHashCodes>(entity.Key),
                                ctx.ResolveNamed <IReadOutputKeysAndHashCodes>(entity.Key),
                                ctx.ResolveNamed <IDelete>(entity.Key)
                                );

                            // since the primary keys from the input may have been transformed into the output, you have to transform before comparing
                            // feels a lot like entity pipeline on just the primary keys... may look at consolidating
                            handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray()));
                            handler.Register(TransformFactory.GetTransforms(ctx, context, primaryKey));
                            handler.Register(new StringTruncateTransfom(context, primaryKey));

                            return(handler);
                        }).Named <IEntityDeleteHandler>(entity.Key);
                    }
                }
            }
        }
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                IPipeline pipeline;
                context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                switch (type)
                {
                case "parallel.linq":
                    pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context));
                    break;

                default:
                    pipeline = new DefaultPipeline(outputController, context);
                    break;
                }

                var output = process.Output();

                // 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 CancelTransform(context));
                pipeline.Register(new IncrementTransform(context));
                pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System)));

                if (ctx.ResolveNamed <IConnectionContext>(entity.Key).Connection.Provider.In("internal", "file", Constants.DefaultSetting))
                {
                    foreach (var field in entity.Fields.Where(f => f.Input && f.Type != "string" && (!f.Transforms.Any() || f.Transforms.First().Method != "convert")))
                    {
                        context.Debug(() => "Automatically adding convert transform");
                        pipeline.Register(new ConvertTransform(new PipelineContext(context.Logger, context.Process, entity, field, new Operation {
                            Method = "convert"
                        })));
                    }
                }

                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)));
                    if (output.Provider == "sqlserver")
                    {
                        pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1)));
                    }
                }

                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);
        }
Example #13
0
        private static string TransformConfiguration(IComponentContext ctx)
        {
            // short hand for parameters is defined, try to transform parameters in advance
            if (!ctx.IsRegisteredWithName <IDependency>("shorthand-p"))
            {
                return(null);
            }

            if (!ctx.IsRegisteredWithName <string>("cfg"))
            {
                return(null);
            }

            var dependencies = new List <IDependency> {
                ctx.Resolve <IReader>(),
                new DateMathModifier(),
                new EnvironmentModifier(new NullPlaceHolderReplacer()),
                ctx.ResolveNamed <IDependency>("shorthand-p")
            };

            var preCfg     = ctx.ResolveNamed <string>("cfg");
            var preProcess = new ConfigurationFacade.Process(preCfg, new Dictionary <string, string>(), dependencies.ToArray());

            var parameters = preProcess.GetActiveParameters();

            if (!parameters.Any(pr => pr.Transforms.Any()))
            {
                return(null);
            }

            var fields = parameters.Select(pr => new Field {
                Name       = pr.Name,
                Alias      = pr.Name,
                Default    = pr.Value,
                Type       = pr.Type,
                Transforms = pr.Transforms.Select(o => o.ToOperation()).ToList()
            }).ToList();
            var len    = fields.Count;
            var entity = new Entity {
                Name = "Parameters", Alias = "Parameters", Fields = fields
            };
            var mini = new Process {
                Name     = "ParameterTransform",
                ReadOnly = true,
                Entities = new List <Entity> {
                    entity
                },
                Maps    = preProcess.Maps.Select(m => m.ToMap()).ToList(),      // for map transforms
                Scripts = preProcess.Scripts.Select(s => s.ToScript()).ToList() // for transforms that use scripts (e.g. js)
            };

            mini.Check(); // very important to check after creating, as it runs validation and even modifies!

            if (!mini.Errors().Any())
            {
                // modification in Check() do not make it out to local variables so overwrite them
                fields = mini.Entities.First().Fields;
                entity = mini.Entities.First();

                var transforms = TransformFactory.GetTransforms(ctx, new PipelineContext(ctx.Resolve <IPipelineLogger>(), mini, entity), fields);

                // make an input out of the parameters
                var input = new List <IRow>();
                var row   = new MasterRow(len);
                for (var i = 0; i < len; i++)
                {
                    row[fields[i]] = parameters[i].Value;
                }

                input.Add(row);

                var output = transforms.Aggregate(input.AsEnumerable(), (rows, t) => t.Operate(rows)).ToList().First();

                for (var i = 0; i < len; i++)
                {
                    var parameter = parameters[i];
                    parameter.Value = output[fields[i]].ToString();
                    parameter.T     = string.Empty;
                    parameter.Transforms.Clear();
                }

                return(preProcess.Serialize());
            }

            var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), mini, entity);

            foreach (var error in mini.Errors())
            {
                context.Error(error);
            }

            return(null);
        }
Example #14
0
        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());
        }