public StandardSqlApplicationInstanceIdRenterTests() { var hostBuilder = new HostBuilder(); hostBuilder.ConfigureServices(services => services.AddSingleton <IExceptionHandler>(new OptionalExceptionHandler(null))); hostBuilder.ConfigureServices(services => services.AddSingleton(sp => new ApplicationInstanceIdSourceDbConnectionFactory(sp, _ => this.CreateDbConnection()))); hostBuilder.ConfigureServices(services => services.AddSingleton <IApplicationInstanceIdSourceTransactionalExecutor>( sp => new SqlTransactionalExecutor(sp.GetRequiredService <ApplicationInstanceIdSourceDbConnectionFactory>()))); this.Host = hostBuilder.Build(); this.Connection = new UndisposableDbConnection(new SQLiteConnection("DataSource=:memory:")); using var command = this.Connection.CreateCommand(); this.Connection.Open(); command.CommandText = $@" CREATE TABLE {TableName} ( id BIGINT PRIMARY KEY, application_name CHAR(50), server_name CHAR(50), creation_datetime DATETIME(3) NOT NULL ) ; "; command.ExecuteNonQuery(); this.Renter = new StandardSqlApplicationInstanceIdRenter(this.Host.Services, databaseName: null); }
public void RentId_WithOnePriorInvocation_ShouldReturnId2() { var exceptionHandler = new OptionalExceptionHandler(null); var connectionFactory = new ApplicationInstanceIdSourceDbConnectionFactory(this.Host.Services, _ => this.CreateDbConnection()); var transactionalExecutor = new SqlTransactionalExecutor(connectionFactory); var otherSource = new StandardSqlApplicationInstanceIdRenter(this.Host.Services, databaseName: null); otherSource.RentId(); var id = this.Renter.RentId(); Assert.Equal(2, id); }
/// <summary> /// <para> /// Registers an implementation based on Standard SQL, which should work with most SQL implementations. /// Use the options to specify the database connection. /// </para> /// <para> /// A vendor-specific implementation is preferred over this. /// Unlike this one, such an implementation may be able to create the table if it does not exist, and it may be optimized for that specific database. /// </para> /// <para> /// This overload takes a generic dependency to inject, and a function to get a <see cref="DbConnection"/> from that dependency. /// The dependency must be registered separately. /// </para> /// <para> /// The type parameter determines the database connection factory to get from the service provider, which should be registered separately. /// </para> /// <para> /// The implementation will throw if the database does not exist, or if the table does not exist. /// </para> /// </summary> /// <param name="getConnectionFromFactory">A function that gets a new <see cref="DbConnection"/> from the registered connection factory.</param> /// <param name="connectionString">Written onto produced <see cref="DbConnection"/> objects, if given. Required only if a <see cref="DbConnection"/> is produced without a connection string.</param> /// <param name="databaseName">If the connection factory's connection string does not specify the database name, specify it here instead.</param> public static ApplicationInstanceIdSourceExtensions.Options UseStandardSql <TDatabaseConnectionFactory>(this ApplicationInstanceIdSourceExtensions.Options options, Func <TDatabaseConnectionFactory, DbConnection> getConnectionFromFactory, string?connectionString = null, string?databaseName = null) where TDatabaseConnectionFactory : class { // Register an IDbConnectionFactory ApplicationInstanceIdSourceDbConnectionFactory.Register(options.Services, getConnectionFromFactory, connectionString); // Register an IApplicationInstanceIdSourceTransactionalExecutor that uses the IDbConnectionFactory options.Services.AddTransient <IApplicationInstanceIdSourceTransactionalExecutor, SqlTransactionalExecutor>(); // Register the IApplicationInstanceIdRenter that uses all of the above options.Services.AddTransient(CreateInstance); return(options); // Local function that creates a new instance IApplicationInstanceIdRenter CreateInstance(IServiceProvider serviceProvider) { var instance = new StandardSqlApplicationInstanceIdRenter(serviceProvider, databaseName); return(instance); } }