حفظ القيم في تطبيق .Net في مرحلة البناء

كانت هناك حاجة لي عند إنشاء التطبيق لتمرير مجموعة من الثوابت للاستخدام في وقت التشغيل. على سبيل المثال ، نريد "خياطة" في التطبيق بعض قيمة السلسلة التي ستعرف في وقت التجميع.

في عالم C ++ ، قمت بحل مثل هذه الأشياء ببساطة باستخدام خيارات التعريف والتجميع. ولكن في .Net تعريف لا تملك قيمًا غير صحيحة / خاطئة ، أي يتم تحديدها أو لا. بقدر ما أفهم ، هدفهم هو أبسط تجميع شرطي.

من يهتم بالحل ، مرحبا بك في القط.

الفكرة الأولى التي زارتني هي إنشاء ملف يحتوي على ثوابت وفقًا للقالب قبل البناء ، لكنني أرغب في الاستغناء عن المدفعية الثقيلة لمحركات القوالب.

بعد البحث ، اكتشفت حقيقة مثيرة للاهتمام. .Net لديه آلية سمة. يمكن أن تتشبث هذه السمات بالفئات والأساليب والحقول وجميع أنواع الكيانات المختلفة. اتضح أنه يمكن توصيله بالتجميع بأكمله.

في ملفات المشروع (.csproj) ، من الممكن تعيين قيم لهذه السمات أثناء التجميع. وفي MSBuild ، يمكنك تمرير المعلمات من الخارج من خلال آلية الخصائص. يبدو أن كل شيء يناسبك ، عليك أن تجرب.

إنشاء تطبيق وحدة تحكم جديد:

% mkdir Example && cd Example
% dotnet new console

نقوم بإنشاء ملف ExampleAttribute.cs مع تعريف السمة الخاصة بنا.

using System;

namespace Example
{

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

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

بعد ذلك ، يتم تقليل ملف Example.csproj إلى النموذج التالي. أضفت تعليقات حتى يكون جوهر التغييرات واضحًا.

<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>

حسنًا ، في الواقع ، الحصول على القيمة في وقت التشغيل في 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}'");
        }
    }
}

لذا ، سنقوم بالتجمع والركض لنرى ما لدينا.

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

والآن مع المعلمة:

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

فويلا ، تم تحقيق الهدف. استخدم على الصحة.

All Articles