HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Having initialization code certain to run only once

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
oncecertainhavingcodeinitializationonlyrun

Problem

I have this static class in an ASP.NET MVC project:

public static class Setup
  {
    private static bool _intialized = false;

    public static void Initialize(IWindsorContainer Container)
    {
      //Check if it has already run
      if (_intialized)
      { return; }

      var connectionString = config.ConnectionStrings["ccsMongo"].ConnectionString;
      var dbName = config.AppSettings["ccsMongoDb"];

      //Initialization code here.
      Container.Register(
          Component.For().ImplementedBy()
            .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName}),
          Component.For().ImplementedBy()
            .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName}),
          Component.For().ImplementedBy()
            .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName})
        );

      //Mark as run
      _intialized = true;
    }
  }


I then include a call to it in my Application_Start. The intent is to be sure that it will never run more than once.

  • Is there a better way to create a function that can't be run more than once in the the application lifetime?



  • Am I being paranoid? I could just put a call to the initialization code into my Application_Start and forget about the "run only once" guard code.



I would be delighted to get any feedback.

Solution

This could execute more than once pretty easily if called on multiple threads at the same time. This should make it a bit more foolproof:

public static class Setup
  {
    private static readonly object _locker = new object();
    private static bool _intialized = false;

    public static void Initialize(IWindsorContainer Container)
    {
      lock (_locker)
      {
        //Check if it has already run
        if (_intialized)
        { return; }

        var connectionString = config.ConnectionStrings["ccsMongo"].ConnectionString;
        var dbName = config.AppSettings["ccsMongoDb"];

        //Initialization code here.
        Container.Register(
            Component.For().ImplementedBy()
              .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName}),
            Component.For().ImplementedBy()
              .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName}),
            Component.For().ImplementedBy()
              .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName})
          );

        //Mark as run
        _intialized = true;
      }
    }
  }

Code Snippets

public static class Setup
  {
    private static readonly object _locker = new object();
    private static bool _intialized = false;

    public static void Initialize(IWindsorContainer Container)
    {
      lock (_locker)
      {
        //Check if it has already run
        if (_intialized)
        { return; }

        var connectionString = config.ConnectionStrings["ccsMongo"].ConnectionString;
        var dbName = config.AppSettings["ccsMongoDb"];

        //Initialization code here.
        Container.Register(
            Component.For<IOrgRepos>().ImplementedBy<OrgRepos>()
              .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName}),
            Component.For<IIndividualRepos>().ImplementedBy<IndividualRepos>()
              .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName}),
            Component.For<IScoreboardRepos>().ImplementedBy<ScoreboardRepos>()
              .DependsOn(new { ConnectionString = connectionString, DatabaseName = dbName})
          );

        //Mark as run
        _intialized = true;
      }
    }
  }

Context

StackExchange Code Review Q#7397, answer score: 3

Revisions (0)

No revisions yet.