protected override void Load(ContainerBuilder builder) { if (_process == null) { return; } // connections foreach (var connection in _process.Connections.Where(c => _ado.Contains(c.Provider))) { // 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)); case "sqlce": return(new SqlCeConnectionFactory(connection)); 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); } //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 <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 "access": case "sqlce": 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 <IInputProvider>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); switch (input.Connection.Provider) { case "mysql": case "postgresql": case "access": case "sqlite": case "sqlce": 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 "postgresql": case "sqlite": case "access": case "sqlce": 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, 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>(); 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 "sqlserver": writer = new SqlServerWriter( output, cf, matcher, new AdoEntityUpdater(output, cf) ); break; case "sqlce": writer = new SqlCeWriter( output, cf, matcher, new AdoEntityUpdater(output, cf) ); break; case "mysql": case "postgresql": case "access": case "sqlite": 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) )); case "mysql": case "postgresql": case "sqlite": case "sqlce": case "sqlserver": 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); // 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)); case "access": return(new AccessUpdateMasterKeysQueryWriter(output, factory)); default: 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 "access": 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 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 "mysql": case "postgresql": case "sqlce": case "access": case "sqlite": case "sqlserver": 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 <IContext>(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 "postgresql": case "access": case "sqlce": case "sqlite": case "sqlserver": 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.Output(); var outputContext = ctx.ResolveNamed <OutputContext>(entity.Key); switch (outputConnection.Provider) { case "mysql": case "postgresql": case "sqlce": case "access": case "sqlite": 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(); 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.Process, context.Entity, primaryKey)); handler.Register(new StringTruncateTransfom(context, primaryKey)); return(new ParallelDeleteHandler(handler)); }).Named <IEntityDeleteHandler>(entity.Key); } } } }
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 == SqlCe)) { // Connection Factory builder.Register <IConnectionFactory>(ctx => new SqlCeConnectionFactory(connection)).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); } // entitiy input foreach (var entity in process.Entities.Where(e => process.Connections.First(c => c.Name == e.Input).Provider == SqlCe)) { // 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)); var dataReader = new AdoInputReader( input, input.InputFields, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key), rowFactory ); return(dataReader); }).Named <IRead>(entity.Key); // INPUT VERSION DETECTOR builder.Register <IInputProvider>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); return(new AdoInputProvider(input, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key))); }).Named <IInputProvider>(entity.Key); } // entity output if (process.GetOutputConnection().Provider == SqlCe) { var calc = process.ToCalculatedFieldsProcess(); // PROCESS OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => { var output = ctx.Resolve <OutputContext>(); if (process.Mode != "init") { return(new NullOutputController()); } 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)); }).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 entity in process.Entities) { builder.Register <IOutputProvider>(ctx => { 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(); IWrite writer = new SqlCeWriter( output, cf, matcher, new AdoEntityUpdater(output, cf) ); 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(); return(new AdoOutputController( output, initializer, ctx.ResolveNamed <IInputProvider>(entity.Key), ctx.ResolveNamed <IOutputProvider>(entity.Key), ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key) )); }).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 AdoUpdateMasterKeysQueryWriter(output, factory)); }).Named <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys"); // MASTER UPDATER builder.Register <IUpdate>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); return(new AdoTwoPartMasterUpdater(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))); }).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); 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((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(); var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key); return(new AdoReader(context, entity.GetPrimaryKey(), ocf, rowFactory, ReadFrom.Output)); })).Named <IReadOutputKeysAndHashCodes>(entity.Key); builder.Register((ctx) => { var outputConnection = process.GetOutputConnection(); var outputContext = ctx.ResolveNamed <OutputContext>(entity.Key); var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key); return(new AdoDeleter(outputContext, ocf)); }).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); } } } }