public static TRepo CreateWriteableRepo <

            TRepo, TEntity, TContext, T>(ConfigurationFactory <T> factory,
                                         string testUser = DEFAULT_USER
                                         )
            where TEntity : class, IHasSysUser, new()
            where TContext : DbContext
            where TRepo : WriteableRepo <TEntity, TContext>
            where T : class
        {
            var databaseName = factory.Configuration.GetDatabaseName <TContext>();
            var instanceName = Guid.NewGuid().ToString();

            TestDbContextManager <TContext> .CreateInMemoryDatabase(
                databaseName, instanceName, out DbContextOptions <TContext> options,
                out TContext context);

            var scopeProperties = new ScopeProperties {
                User = testUser
            };


            scopeProperties.OtherProperties.Add("InstanceName", instanceName);
            scopeProperties.OtherProperties.Add("DbContextOptions", options);

            var repo = Activator.CreateInstance(typeof(TRepo),
                                                new object[] { context, scopeProperties }) as TRepo;

            return(repo);
        }
        public async Task InvokeAsync(HttpContext context, IServiceProvider provider,
                                      IConfiguration config,
                                      ILogger <RepoInterceptor <TRepo, TEntity, TContext> > logger)
        {
            _logger = logger;

            _logger.LogInformation($"RepoInterceptor handling request: {context.Request.Path}");


            if (!context.Request.Path.StartsWithSegments(new PathString("/swagger")))
            {
                var header = GetTestingHeader(context);

                if (header.Key == null)
                {
                    var defaultInstanceName = DEFAULT_NAMED_INSTANCE;
                    try {
                        if (context.Session != null)
                        {
                            defaultInstanceName = context.Session.Id;
                        }
                    } catch { }

                    context.Request.Headers.Add(HDR_USE_INMEMORY, defaultInstanceName);
                    header = new KeyValuePair <string, string>(HDR_USE_INMEMORY, defaultInstanceName);
                }

                _logger.LogInformation($"RepoInterceptor processing header {header.Key}: {header.Value}");

                var operation        = header.Key;
                var baseInstanceName = header.Value;

                var repo  = provider.GetRequiredService(typeof(TRepo)) as TRepo;
                var cache = provider.GetRequiredService(typeof(TestDbContextOptionsCache <TContext>))
                            as TestDbContextOptionsCache <TContext>;

                var baseDatabaseName = TestDbContextManager <TContext> .BaseDatabaseName(config);

                if (operation == HDR_USE_RELATIONAL)
                {
                    _logger.LogInformation($"Using Relational database");
                }
                else if (operation == HDR_USE_READONLY)
                {
                    throw new ApplicationException("HDR_USE_READONLY not appropriate for Writeable Repo.");
                }
                else if (operation == HDR_USE_INMEMORY)
                {
                    GetOrAddInMemoryDatabase(repo, cache, baseInstanceName, baseDatabaseName);
                }
                else if (operation == HDR_DROP_INMEMORY)
                {
                    DropInMemory(cache, baseInstanceName);
                }
            }

            await _next(context);
        }
예제 #3
0
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    TestDbContextManager <TContext> .DropInMemoryDatabase(Repo.Context);
                }
                disposedValue = true;
            }
        }
예제 #4
0
        private void DropInMemory(TestDbContextCache <TContext> cache, string instanceName)
        {
            if (cache.ContainsKey(instanceName))
            {
                _logger.LogInformation($"Dropping in-memory history instance {instanceName} for {typeof(TContext).Name}");
                var context = cache[instanceName];
                TestDbContextManager <TContext> .DropInMemoryDatabase(context);

                cache.Remove(instanceName);
            }
        }
        public static TRepo CreateReadonlyRepo <

            TRepo, TEntity, TContext, T>(ConfigurationFactory <T> factory)
            where TEntity : class, new()
            where TContext : DbContext
            where TRepo : ReadonlyRepo <TEntity, TContext>
            where T : class
        {
            var context = TestDbContextManager <TContext> .GetReadonlyDatabase(
                factory.Configuration);

            var repo = Activator.CreateInstance(typeof(TRepo),
                                                new object[] { context }) as TRepo;

            return(repo);
        }
예제 #6
0
        private void GetOrAddInMemoryDatabase(TRepo repo, TestDbContextCache <TContext> cache,
                                              string instanceName, string baseDatabaseName)
        {
            if (cache.ContainsKey(instanceName))
            {
                repo.Context = cache[instanceName];
                _logger.LogInformation($"Using existing in-memory database {baseDatabaseName}, instance = {instanceName}");
            }
            else
            {
                _logger.LogInformation($"Creating in-memory database {baseDatabaseName}, instance = {instanceName}");
                var dbContext = TestDbContextManager <TContext> .CreateInMemoryDatabase(baseDatabaseName, instanceName);

                repo.Context = dbContext;
                repo.Context.Database.EnsureCreated();
                cache.Add(instanceName, repo.Context);
            }
        }
        public static TRepo CreateWriteableTemporalRepo <
            TRepo, TEntity, TContext, THistoryContext, T>(ConfigurationFactory <T> factory,
                                                          string testUser = DEFAULT_USER
                                                          )

            where TEntity : class, IEFCoreTemporalModel, new()
            where TContext : DbContext
            where THistoryContext : DbContext
            where TRepo : WriteableTemporalRepo <TEntity, TContext, THistoryContext>
            where T : class
        {
            var databaseName = factory.Configuration.GetDatabaseName <TContext>();
            var instanceName = Guid.NewGuid().ToString();

            var historyDatabaseName = factory.Configuration.GetDatabaseName <THistoryContext>();
            var historyInstanceName = instanceName + Interceptor.HISTORY_INSTANCE_SUFFIX;


            TestDbContextManager <TContext> .CreateInMemoryDatabase(
                databaseName, instanceName, out DbContextOptions <TContext> options,
                out TContext context);

            TestDbContextManager <THistoryContext> .CreateInMemoryDatabase(
                historyDatabaseName, historyInstanceName,
                out DbContextOptions <THistoryContext> historyOptions,
                out THistoryContext historyContext);

            var scopeProperties = new ScopeProperties {
                User = testUser
            };

            scopeProperties.OtherProperties.Add("InstanceName", instanceName);
            scopeProperties.OtherProperties.Add("HistoryInstanceName", historyInstanceName);
            scopeProperties.OtherProperties.Add("DbContextOptions", options);
            scopeProperties.OtherProperties.Add("HistoryDbContextOptions", historyOptions);


            var repo = Activator.CreateInstance(typeof(TRepo),
                                                new object[] { context, historyContext, scopeProperties }) as TRepo;

            return(repo);
        }
        private void GetOrAddInMemoryHistoryDatabase(TRepo repo,
                                                     TestDbContextOptionsCache <THistoryContext> cache,
                                                     string instanceName, string baseDatabaseName)
        {
            if (cache.ContainsKey(instanceName))
            {
                _logger.LogInformation($"Using existing in-memory history database {baseDatabaseName}, instance = {instanceName}");
                TestDbContextManager <THistoryContext> .CreateInMemoryDatabase(cache[instanceName], out THistoryContext context);

                repo.HistoryContext = context;
            }
            else
            {
                _logger.LogInformation($"Creating in-memory history database {baseDatabaseName}, instance = {instanceName}");
                TestDbContextManager <THistoryContext> .CreateInMemoryDatabase(baseDatabaseName, instanceName,
                                                                               out DbContextOptions <THistoryContext> options, out THistoryContext context);

                repo.HistoryContext = context;
                repo.HistoryContext.Database.EnsureCreated();
                cache.Add(instanceName, options);
            }
        }