testcontainers-dotnet icon indicating copy to clipboard operation
testcontainers-dotnet copied to clipboard

Easy way to add a test container as an hosted service

Open srollinet opened this issue 3 years ago • 1 comments

I use TestContainers a lot in my integration tests with libs like alba that allow to build a test server. Most of the time, the container life time is the same as the test server.

It would be great to have an easy way to setup a test container and run it as an hosted service in a generic host.

I can suggest something and make a PR if you are ok with this idea.

The basic idea would be something like that

    /// <summary>
    /// Extension methods for <see cref="IServiceCollection"/>.
    /// </summary>
    public static class GenericHostExtension
    {
        public static IServiceCollection AddTestContainer<T>(
            this IServiceCollection services,
            Action<ContainerBuilder<T>> configureDelegate)
            where T : IContainer
        {
            var builder = new ContainerBuilder<T>();
            configureDelegate(builder);

            var container = builder.Build();
            services.AddHostedService(s => new ContainerHostedService<T>(container));

            return services;
        }

        public static IServiceCollection AddAdoTestContainer<T>(
            this IServiceCollection services,
            string connectionStringName,
            Action<ContainerBuilder<T>> configureDelegate)
            where T : AdoNetContainer
        {
            var builder = new ContainerBuilder<T>();
            configureDelegate(builder);

            var container = builder.Build();
            services.AddHostedService(s => new ContainerHostedService<T>(container));

            //TODO Inject the connection string in the configuration with the key 'connectionStringName'

            return services;
        }
    }

    internal class ContainerHostedService<T> : IHostedService where T : IContainer
    {
        private readonly T _container;

        public ContainerHostedService(T container)
        {
            _container = container;
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            await _container.StartAsync(cancellationToken);
        }

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            await _container.StartAsync(cancellationToken);
        }
    }

It will also be possible to inject all the logging related stuff in the container

srollinet avatar Jan 31 '22 17:01 srollinet

I think this is a great idea! However, I think we should not couple this into the main project. Eg we can support this in a separate project specific to hosted services.

Something like this: https://github.com/jinhong-/testcontainers-environment-dotnet

isen-ng avatar Feb 03 '22 03:02 isen-ng