gameloverr2
gameloverr2

Reputation: 95

Autofac custom configuration in C#

I have 3 classes Class1, 2 and 3 and a class Manage

public class Class1
{
  public void PrintMessageForClass1()
  {
     Console.WriteLine("This is class1");
  }
}


public class Class2
{
  public void PrintMessageForClass2()
  {
     Console.WriteLine("This is class2");
  }
}

public class Class3
{
  public void PrintMessageForClass3()
  {
     Console.WriteLine("This is class3");
  }
}


public class Manage
{
  Class1 c1;
  Class2 c2;
  Class3 c3;

  public Manage (Class1 c1, Class2 c2 ,Class3 c3)
  {
     this.c1 = c1;
     this.c2 = c2;
     this.c3 = c3;
  }

  public void Print()
  {
      c1.PrintMessageForClass1();
      c2.PrintMessageForClass2();
      c3.PrintMessageForClass3();
   }    
}

Then I use autofac as folllows

class ContainerConfig
{
   public static IContainer Configure()
   {
       var builder = new ContainerBuilder();

       builder.RegisterType<Manage>().AsSelf();

       builder.RegisterType<Class1>().AsSelf();
       builder.RegisterType<Class2>().AsSelf();
       builder.RegisterType<Class3>().AsSelf();

      return builder.Build();
   }
}

In class Program:

 class Program
 {
     static void Main(string[] args)
     {
        var container = ContainerConfigcs.Configure();

        using (var scope = container.BeginLifetimeScope())
         {
              var c = container.Resolve<Manage>();
              c.Print();
         }
     }
 }

For now, the output is:

This is class1
This is class2
This is class3

But I want to use an App.config where in the appsettings I can have a value like 1,2 or 3. For this example I set the value to 1

 <appSettings>
    <add key="classType" value="1" />
  </appSettings>

I want to use this value from App.config to make autofac use only one of the three classes. For example, if the value is 1, I want to use the Class1, so on the console will be printed only This is class1. If I change the value to 2, I want autofac to use Class2, and so on.

How can I set autofac to receive the value in AppConfig?

Upvotes: 0

Views: 579

Answers (1)

Junior
Junior

Reputation: 196

You should be able to use ConfigurationManager.AppSettings from System.Configuration so you can extract the appConfig. https://learn.microsoft.com/en-us/dotnet/api/system.configuration.configurationmanager.appsettings?view=dotnet-plat-ext-3.1

You can access appSettings by the classType key, and then switch based on that. Now we have the classType value, we can decide exactly where we want to use it. I propose two options, in order of recommendation.

Autofac does not fully apply to your question. If you want the switching to occur only by Autofac, Class1, Class2 and Class3 must implement the same interface.. say IPrintStuff. Then in your container config, you register one of the implementations of IPrintStuff.

public static IContainer Configure()
{
   var builder = new ContainerBuilder();
   var classType = System.Configuration.ConfigurationManager.AppSettings["classType"].ToString();

   builder.RegisterType<Manage>().AsSelf();

    switch(classType)
    {
      case "1":
          builder.RegisterType<Class1>().As<IPrintStuff>();
      break;
      case "2":
          builder.RegisterType<Class2>().As<IPrintStuff>();
      break;
      case "3":
          builder.RegisterType<Class3>().As<IPrintStuff>();
      break;
    }

  return builder.Build();
}

(And then Manage does not take in 3 classes anymore, it takes 1 parameter of type IPrintStuff)

The other approach is to do it a bit higher up, in Manage.cs. It is still disadvantageous because you still have to new up the 3 objects, but only call one.

Manage.cs

public void Print()
{ 
    var classType = System.Configuration.ConfigurationManager.AppSettings["classType"];
    switch(classType)
    {
      case "1":
          c1.PrintMessageForClass1();
      break;
      case "2":
          c2.PrintMessageForClass2();
      break;
      case "3":
          c3.PrintMessageForClass3();
      break;
    }
}

Upvotes: 2

Related Questions