Skip to content

Commit

Permalink
feat(#493): Add .NET module template (#742)
Browse files Browse the repository at this point in the history
  • Loading branch information
HofmeisterAn authored Jan 26, 2023
1 parent 478efc5 commit 9412673
Show file tree
Hide file tree
Showing 17 changed files with 236 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<Product>Testcontainers</Product>
<Copyright>Copyright (c) 2019 - 2022 Andre Hofmeister and other authors</Copyright>
<Copyright>Copyright (c) 2019 - 2023 Andre Hofmeister and other authors</Copyright>
<Authors>Andre Hofmeister and contributors</Authors>
<Company>Andre Hofmeister</Company>
<Description>Testcontainers for .NET is a library to support tests with throwaway instances of Docker containers for all compatible .NET Standard versions.</Description>
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2019 - 2022 Andre Hofmeister and other authors
Copyright (c) 2019 - 2023 Andre Hofmeister and other authors

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ See [LICENSE](https://github.com/testcontainers/testcontainers-dotnet/blob/maste

## Copyright

Copyright (c) 2019 - 2022 Andre Hofmeister and other authors.
Copyright (c) 2019 - 2023 Andre Hofmeister and other authors.

See [contributors][testcontainers-dotnet-contributors] for all contributors.

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ See [LICENSE](https://raw.githubusercontent.com/testcontainers/testcontainers-do

## Copyright

Copyright (c) 2019 - 2022 Andre Hofmeister and other authors.
Copyright (c) 2019 - 2023 Andre Hofmeister and other authors.

See [contributors][testcontainers-dotnet-contributors] for all contributors.

Expand Down
44 changes: 44 additions & 0 deletions src/Templates/CSharp/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "Andre Hofmeister and contributors",
"description": "A .NET template to scaffold advanced Testcontainers for .NET modules.",
"classifications": ["Test", "Testcontainers"],
"groupIdentity": "Testcontainers",
"identity": "Testcontainers.Module.CSharp",
"name": "Testcontainers Module Project",
"shortName": "tcm",
"sourceName": "ModuleName",
"symbols": {
"official-module": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "false",
"description": "Determines whether the template generates an official module or not."
},
"official-module-prefix": {
"type": "generated",
"datatype": "text",
"generator": "switch",
"fileRename": "Testcontainers.",
"replaces": "Testcontainers.",
"parameters": {
"cases": [
{
"condition": "official-module",
"value": "Testcontainers.",
"description": "Keep the Testcontainers official module prefix."
}
]
},
"onlyIf": [
{
"after": "namespace "
}
]
}
},
"tags": {
"language": "C#",
"type": "project"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
namespace Testcontainers.ModuleName;

/// <inheritdoc cref="ContainerBuilder{TBuilderEntity, TContainerEntity, TConfigurationEntity}" />
[PublicAPI]
public sealed class ModuleNameBuilder : ContainerBuilder<ModuleNameBuilder, ModuleNameContainer, ModuleNameConfiguration>
{
/// <summary>
/// Initializes a new instance of the <see cref="ModuleNameBuilder" /> class.
/// </summary>
public ModuleNameBuilder()
: this(new ModuleNameConfiguration())
{
// 1) To change the ContainerBuilder default configuration override the DockerResourceConfiguration property and the "ModuleNameBuilder Init()" method.
// Append the module configuration to base.Init() e.g. base.Init().WithImage("alpine:3.17") to set the modules' default image.

// 2) To customize the ContainerBuilder validation override the "void Validate()" method.
// Use Testcontainers' Guard.Argument<TType>(TType, string) or your own guard implementation to validate the module configuration.

// 3) Add custom builder methods to extend the ContainerBuilder capabilities such as "ModuleNameBuilder WithModuleNameConfig(object)".
// Merge the current module configuration with a new instance of the immutable ModuleNameConfiguration type to update the module configuration.

// DockerResourceConfiguration = Init().DockerResourceConfiguration;
}

/// <summary>
/// Initializes a new instance of the <see cref="ModuleNameBuilder" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
private ModuleNameBuilder(ModuleNameConfiguration resourceConfiguration)
: base(resourceConfiguration)
{
// DockerResourceConfiguration = resourceConfiguration;
}

// /// <inheritdoc />
// protected override ModuleNameConfiguration DockerResourceConfiguration { get; }

// /// <summary>
// /// Sets the ModuleName config.
// /// </summary>
// /// <param name="config">The ModuleName config.</param>
// /// <returns>A configured instance of <see cref="ModuleNameBuilder" />.</returns>
// public ModuleNameBuilder WithModuleNameConfig(object config)
// {
// // Extends the ContainerBuilder capabilities and holds a custom configuration in ModuleNameConfiguration.
// // In case of a module requires other properties to represent itself, extend ContainerConfiguration.
// return Merge(DockerResourceConfiguration, new ModuleNameConfiguration(config: config));
// }

/// <inheritdoc />
public override ModuleNameContainer Build()
{
Validate();
return new ModuleNameContainer(DockerResourceConfiguration, TestcontainersSettings.Logger);
}

// /// <inheritdoc />
// protected override ModuleNameBuilder Init()
// {
// return base.Init();
// }

// /// <inheritdoc />
// protected override void Validate()
// {
// base.Validate();
// }

/// <inheritdoc />
protected override ModuleNameBuilder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
{
return Merge(DockerResourceConfiguration, new ModuleNameConfiguration(resourceConfiguration));
}

/// <inheritdoc />
protected override ModuleNameBuilder Clone(IContainerConfiguration resourceConfiguration)
{
return Merge(DockerResourceConfiguration, new ModuleNameConfiguration(resourceConfiguration));
}

/// <inheritdoc />
protected override ModuleNameBuilder Merge(ModuleNameConfiguration oldValue, ModuleNameConfiguration newValue)
{
return new ModuleNameBuilder(new ModuleNameConfiguration(oldValue, newValue));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace Testcontainers.ModuleName;

/// <inheritdoc cref="ContainerConfiguration" />
[PublicAPI]
public sealed class ModuleNameConfiguration : ContainerConfiguration
{
/// <summary>
/// Initializes a new instance of the <see cref="ModuleNameConfiguration" /> class.
/// </summary>
public ModuleNameConfiguration(object config = null)
{
// // Sets the custom builder methods property values.
// Config = config;
}

/// <summary>
/// Initializes a new instance of the <see cref="ModuleNameConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public ModuleNameConfiguration(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
: base(resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}

/// <summary>
/// Initializes a new instance of the <see cref="ModuleNameConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public ModuleNameConfiguration(IContainerConfiguration resourceConfiguration)
: base(resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}

/// <summary>
/// Initializes a new instance of the <see cref="ModuleNameConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public ModuleNameConfiguration(ModuleNameConfiguration resourceConfiguration)
: this(new ModuleNameConfiguration(), resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}

/// <summary>
/// Initializes a new instance of the <see cref="ModuleNameConfiguration" /> class.
/// </summary>
/// <param name="oldValue">The old Docker resource configuration.</param>
/// <param name="newValue">The new Docker resource configuration.</param>
public ModuleNameConfiguration(ModuleNameConfiguration oldValue, ModuleNameConfiguration newValue)
: base(oldValue, newValue)
{
// // Create an updated immutable copy of the module configuration.
// Config = BuildConfiguration.Combine(oldValue.Config, newValue.Config);
}

// /// <summary>
// /// Gets the ModuleName config.
// /// </summary>
// public object Config { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Testcontainers.ModuleName;

/// <inheritdoc cref="DockerContainer" />
[PublicAPI]
public sealed class ModuleNameContainer : DockerContainer
{
/// <summary>
/// Initializes a new instance of the <see cref="ModuleNameContainer" /> class.
/// </summary>
/// <param name="configuration">The container configuration.</param>
/// <param name="logger">The logger.</param>
public ModuleNameContainer(IContainerConfiguration configuration, ILogger logger)
: base(configuration, logger)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)src/Testcontainers/Testcontainers.csproj"/>
</ItemGroup>
</Project>
6 changes: 6 additions & 0 deletions src/Templates/CSharp/Testcontainers.ModuleName/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
global using Docker.DotNet.Models;
global using DotNet.Testcontainers.Builders;
global using DotNet.Testcontainers.Configurations;
global using DotNet.Testcontainers.Containers;
global using JetBrains.Annotations;
global using Microsoft.Extensions.Logging;
Empty file added src/Templates/FSharp/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions src/Templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# .NET module template

The .NET module template scaffolds Testcontainers for .NET modules. While simple modules can inherit from `ContainerBuilder`, more advanced modules usually require additional properties and methods to set up a running configuration. To scaffold a new module, install the template `dotnet new install ./src/Templates` and run `dotnet new tcm --name ${module_name} ----output ${output_directory}`.
Empty file.
2 changes: 1 addition & 1 deletion src/Testcontainers/Builders/BuildConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace DotNet.Testcontainers.Builders
using System.Collections.Generic;
using System.Linq;

internal static class BuildConfiguration
public static class BuildConfiguration
{
/// <summary>
/// Returns the changed configuration object. If there is no change, the previous configuration object is returned.
Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers/Builders/ContainerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public ContainerBuilder()
/// Initializes a new instance of the <see cref="ContainerBuilder" /> class.
/// </summary>
/// <param name="dockerResourceConfiguration">The Docker resource configuration.</param>
private ContainerBuilder(IContainerConfiguration dockerResourceConfiguration)
protected ContainerBuilder(IContainerConfiguration dockerResourceConfiguration)
: base(dockerResourceConfiguration)
{
this.DockerResourceConfiguration = dockerResourceConfiguration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public interface IAbstractBuilder<out TBuilderEntity, out TResourceEntity, out T
/// Builds an instance of <typeparamref name="TResourceEntity" /> with the given resource configuration.
/// </summary>
/// <returns>A configured instance of <typeparamref name="TResourceEntity" />.</returns>
/// <exception cref="ArgumentException">Thrown when a mandatory Docker resource configuration is not set.</exception>
[PublicAPI]
TResourceEntity Build();
}
Expand Down

0 comments on commit 9412673

Please sign in to comment.