Modül başlatıcılarıModule Initializers

ÖzetSummary

.NET platformunda derleme için başlatma kodunu yazmayı doğrudan destekleyen bir özelliği olsa da (Teknik olarak, modül) C# dilinde gösterilmez.Although the .NET platform has a feature that directly supports writing initialization code for the assembly (technically, the module), it is not exposed in C#. Bu bir sunarak pazarların senaryosudur, ancak bu bir kez çalıştırdığınızda çözümler oldukça doğru görünür.This is a rather niche scenario, but once you run into it the solutions appear to be pretty painful. Bir dizi müşterinin (Microsoft 'un içinde ve dışında) sorun ile ilgili raporları vardır ve daha fazla belgelenmemiş servis talebi yoktur.There are reports of a number of customers (inside and outside Microsoft) struggling with the problem, and there are no doubt more undocumented cases.

MotivasyonMotivation

  • En az ek yük ve kullanıcının açık bir şekilde çağrı yapması gerekmeden, bir kez yüklendiğinde, bir kerelik başlatma yapmak için kitaplıkları etkinleştirinEnable libraries to do eager, one-time initialization when loaded, with minimal overhead and without the user needing to explicitly call anything
  • Geçerli Oluşturucu yaklaşımlarının belirli bir nedeni, static çalışma zamanının statik Oluşturucu içeren bir türün kullanımıyla ilgili ek denetimler yapması ve statik oluşturucunun çalıştırılıp çalıştırılmayacağı konusunda daha fazla denetim yapması gerektiğinden emin değildir.One particular pain point of current static constructor approaches is that the runtime must do additional checks on usage of a type with a static constructor, in order to decide whether the static constructor needs to be run or not. Bu, ölçülebilir ek yük ekler.This adds measurable overhead.
  • Kullanıcı açıkça herhangi bir şeyi çağırmaya gerek olmadan, bazı genel başlatma mantığını çalıştırmak için kaynak oluşturucularını etkinleştirinEnable source generators to run some global initialization logic without the user needing to explicitly call anything

Ayrıntılı tasarımDetailed design

Bir yöntem, bir öznitelik ile dekorasyon bir modül başlatıcısı olarak belirlenebilir [ModuleInitializer] .A method can be designated as a module initializer by decorating it with a [ModuleInitializer] attribute.

using System;
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public sealed class ModuleInitializerAttribute : Attribute { }
}

Özniteliği şu şekilde kullanılabilir:The attribute can be used like this:

using System.Runtime.CompilerServices;
class C
{
    [ModuleInitializer]
    internal static void M1()
    {
        // ...
    }
}

Bazı gereksinimler, Bu öznitelikle hedeflenen yönteme uygulanmaktadır:Some requirements are imposed on the method targeted with this attribute:

  1. Yöntemi olmalıdır static .The method must be static.
  2. Yöntemin parametresiz olması gerekir.The method must be parameterless.
  3. Yöntemin dönmesi gerekir void .The method must return void.
  4. Yöntem genel olmamalı veya genel türde içerilmemelidir.The method must not be generic or be contained in a generic type.
  5. Yönteme, kapsayan modülden erişilebilir olması gerekir.The method must be accessible from the containing module.
    • Bu, yöntemin Etkin Erişilebilirlik veya olması gereken anlamına internal gelir public .This means the method's effective accessibility must be internal or public.
    • Bu ayrıca yöntemin yerel bir işlev olamayacağı anlamına gelir.This also means the method cannot be a local function.

Bir derlemede bu özniteliğe sahip bir veya daha fazla geçerli yöntem bulunduğunda, derleyici öznitelikli yöntemlerin her birini çağıran bir modül başlatıcısı yayacaktır.When one or more valid methods with this attribute are found in a compilation, the compiler will emit a module initializer which calls each of the attributed methods. Çağrılar ayrılmış, ancak belirleyici bir sırayla yayılır.The calls will be emitted in a reserved, but deterministic order.

BulunmaktadırDrawbacks

Neden bunu yapamıyoruz?Why should we not do this?

  • "Ekleme" modül başlatıcıları için var olan üçüncü taraf araçları, bu özelliği isteyen kullanıcılar için yeterlidir.Perhaps the existing third-party tooling for "injecting" module initializers is sufficient for users who have been asking for this feature.

Tasarım toplantılarıDesign meetings

8 Nisan, 2020April 8th, 2020