public static IDataBuilder AddAccessor <TAccessor, TImplementation>(this IDataBuilder builder,
                                                                            Action <ITenant, DbContextOptionsBuilder> setupAction, int poolSize = 128)
            where TAccessor : class, IAccessor
            where TImplementation : DbContext, TAccessor
        {
            builder.NotNull(nameof(builder));
            setupAction.NotNull(nameof(setupAction));

            var mapper = AccessorTypeParameterMappingHelper.ParseMapper(typeof(TImplementation));

            builder.SetProperty(p => p.AccessorTypeParameterMapper, mapper);

            if (poolSize > 0)
            {
                builder.Services.AddDbContextPool <TAccessor, TImplementation>(ConfigureOptionsBuilder, poolSize);
            }
            else
            {
                builder.Services.AddDbContext <TAccessor, TImplementation>(ConfigureOptionsBuilder);
            }

            builder.Services.TryAddScoped(sp => (TImplementation)sp.GetRequiredService <TAccessor>());

            return(builder
                   .AddInternalAccessorServices()
                   .AddDesignTimeServices <TImplementation>());

            // ConfigureOptionsBuilder
            void ConfigureOptionsBuilder(IServiceProvider applicationServiceProvider,
                                         DbContextOptionsBuilder optionsBuilder)
            {
                optionsBuilder.ReplaceServices();

                if (builder.MemoryCache.IsNull())
                {
                    var memoryCache = applicationServiceProvider.GetRequiredService <IMemoryCache>();
                    memoryCache.SetDataBuilder(builder);

                    builder.SetProperty(p => p.MemoryCache, memoryCache);
                    optionsBuilder.UseMemoryCache(memoryCache);
                }

                setupAction.Invoke((builder.Dependency as DataBuilderDependency).Options.DefaultTenant,
                                   optionsBuilder);
            }
        }