Open sandboxFocusImprove this doc

PS0229: Invalid Module Initializer Method

Severity Error
Reported by PostSharp
Message Method "<Method>" must be static, non-generic, parameterless, return void, and be public or internal in a public or internal type because of [ModuleInitializer].

Cause

The ModuleInitializerAttribute attribute makes PostSharp call a method from the module initializer of the assembly, which runs when the assembly is loaded. PostSharp calls the method from code that has no instance and no arguments to pass, so the method must have the following shape:

  • It is static.
  • It has no parameters and returns void.
  • It has no generic parameters.
  • It is public, internal or protected internal, and so are all the types that contain it. A public method of a private nested type is rejected.

PostSharp reports PS0229 on each method marked with ModuleInitializerAttribute that breaks one of these rules, and does not call it.

In the following example, the Initialize method is private.

using System;
using PostSharp.Aspects;

namespace Errors.PS0229_Error;

public static class Startup
{
    public static string Culture { get; private set; } = "";

    // A module initializer cannot be private.
    [ModuleInitializer( 0 )]
    private static void Initialize()
    {
        Culture = "en-US";
    }
}

public static class Program
{
    public static void Main()
    {
        Console.WriteLine( $"Culture: {Startup.Culture}" );
    }
}
error PS0229: PS0229_Error.cs(12,25): Method "Errors.PS0229_Error.Startup.Initialize" must be static, non-generic, parameterless, return void, and be public or internal in a public or internal type because of [ModuleInitializer].

Resolution

Change the method so that it meets the rules above: make it internal or public, static, without parameters, without generic parameters and returning void. When the method is in a private or protected nested type, move it to a type that is internal or public. When the initialization needs a value, read it from the method instead of passing it as a parameter.

In the following example, Initialize is internal, and PostSharp calls it before Main runs.

using System;
using PostSharp.Aspects;

namespace Errors.PS0229_Fixed;

public static class Startup
{
    public static string Culture { get; private set; } = "";

    // The module initializer is internal, so the module constructor can call it.
    [ModuleInitializer( 0 )]
    internal static void Initialize()
    {
        Culture = "en-US";
    }
}

public static class Program
{
    public static void Main()
    {
        Console.WriteLine( $"Culture: {Startup.Culture}" );
    }
}
Culture: en-US

See Also

Reference

ModuleInitializerAttribute

Other Resources

Executing Code Just After the Assembly is Loaded