Enregistrement de valeurs dans une application .Net au stade de la création

Il était nécessaire pour moi lors de la construction de l'application de transmettre un ensemble de constantes à utiliser lors de l'exécution. Par exemple, nous voulons «coudre» dans l'application une valeur de chaîne qui sera connue au moment de l'assemblage.

Dans le monde C ++, j'ai résolu de telles choses très simplement en utilisant les options de définition et de compilation. Mais dans .Net, ne définissez pas de valeurs autres que true / false, c'est-à-dire ils sont identifiés ou non. Autant que je sache, leur objectif est la compilation conditionnelle la plus simple.

Qui se soucie de la solution, bienvenue au chat.

La première pensée qui m'a rendu visite a été de générer un fichier avec des constantes selon le modèle avant la construction, mais je voudrais faire sans impliquer l'artillerie lourde des moteurs de modèle.

Après quelques recherches, j'ai découvert un fait intéressant. .Net a un mécanisme d'attribut. Ces attributs peuvent s'accrocher aux classes, méthodes, champs et toutes sortes d'entités différentes. Il s'est avéré qu'il peut être accroché à l'ensemble de l'assemblage.

Dans les fichiers de projet (.csproj), il est possible de définir des valeurs pour ces attributs lors de l'assemblage. Et dans MSBuild, vous pouvez passer des paramètres de l'extérieur via le mécanisme des propriétés. Il semble que tout rentre, il faut essayer.

Créez une nouvelle application console:

% mkdir Example && cd Example
% dotnet new console

Nous créons le fichier ExampleAttribute.cs avec la définition de notre attribut.

using System;

namespace Example
{

[AttributeUsage(AttributeTargets.Assembly)] //     
public class ExampleAttribute : Attribute
{
    public string Value { get; set; }

    public ExampleAttribute(string value)
    {
        Value = value;
    }
}
 
}

Ensuite, le fichier Example.csproj est réduit au format suivant. J'ai ajouté des commentaires pour que l'essence des changements soit claire.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RootNamespace>Example</RootNamespace>

    <ExampleValue>default</ExampleValue> <!--        -->
  </PropertyGroup>

  <!--          -->
  <ItemGroup>
    <AssemblyAttribute Include="Example.ExampleAttribute"> <!--    -->
      <_Parameter1>$(ExampleValue)</_Parameter1> <!--      -->
    </AssemblyAttribute>
  </ItemGroup>

</Project>

Eh bien, en fait, obtenir la valeur à l'exécution dans Project.cs

using System;
using System.Reflection;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var attr = (ExampleAttribute) assembly.GetCustomAttribute(typeof(ExampleAttribute));
            Console.WriteLine($"Assembly attribute value = '{attr.Value}'");
        }
    }
}

Donc, nous allons assembler et courir afin de voir ce que nous avons.

% dotnet build .
% dotnet run --no-build .
Assembly attribute value = 'default'

Et maintenant avec le paramètre:

% dotnet build . /p:ExampleValue="NOT DEFAULT"
% dotnet run --no-build .
Assembly attribute value = 'NOT DEFAULT'

Voila, l'objectif a été atteint. Utilisation sur la santé.

All Articles