2
votes

We are migrating a .NET Framework application(MVC) to a .NET Core 3 application (MVC). We have a scenario as follows:

Flow 1: ClassX instantiated by ControllerA

Flow 2: ClassX instantiated by ClassY instantiated by ClassZ instantiated by ClassD instantiated by Controller B

(ControllerA and ControllerB are part of the MVC Project. Classes X, Y, Z, D are part of a class library referenced by the MVC project. )

In the old .NET Framework project, log4net was used and static ILog objects were created in every class using LogManager.GetLogger. But ASP.NET Core uses DI principle. So from my understanding, the ILoggerFactory is injected into the Controllers A and B at Startup time. The loggerFactory can be passed from ControllerB to the ClassX, from ClassX to ClassY and so on, in Flow 2.

Only ClassX needs logging and not the other classes Y, Z and D in Flow 2.

Is there an alternative approach for doing logging with ILogger in this scenario, without changing the intermediate class constructors(Y, Z, D)?

1
Please add some code. Do you have control over the library code? Will changing it affect other projects of yours?Fildor

1 Answers

3
votes

Instead of instantiating a depended class inside your controller, delegate this responsibility to .NET Core inbuilt DI container - This will help you to inject the depended class directly to the required class.

Below code snippet will help you how to use DI in your existing codebase.

 public class Startup
 {
    ...
    public void ConfigureServices(IServiceCollection services)
    {      
      services.AddLogging();
      services.AddTransient<ClassX>();
      services.AddTransient<ClassY>();
      services.AddTransient<ClassZ>();
      services.AddTransient<ClassD>();
      ...
    }
}

public class ControllerB : ControllerBase
{
    private readonly ClassD classD;
    private readonly ILogger logger;

    public ControllerB(ClassD classD, ILogger<ControllerB> logger)
    {
        this.classD = classD;
        this.logger = logger;
    }
    ...
}

public class ClassD
{
   private readonly ClassZ classZ;

   public ClassD(ClassZ classZ)
   {
       this.classZ = classZ;
   }
} //Do the same thing for ClassZ and ClassY

public class ClassX
{
   private readonly ILogger logger;

   public ClassX(ILogger<ClassX> logger)
   {
       this.logger = logger;
   }
}