You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Framework4.6.1中依赖注入构建日志基础设施,工厂类初始化NLog.Logger

Alright, let's tackle this problem step by step. You're working in .NET Framework 4.6.1, want to build a logging infrastructure with dependency injection, use a factory to initialize NLog.Logger instances, and skip Unity's LoggerFactory.Resolve() method. Here's a solid, Unity-free approach:

核心思路

Instead of relying on Unity's built-in resolution, we'll create our own lightweight logging abstraction, wrap NLog in it, build a factory to handle NLog instance creation, and integrate this with a flexible dependency injection container (we'll use Microsoft's DI package since it's compatible with Framework 4.6.1 and doesn't lock you into Unity).

Step 1: Define a Logging Abstraction

First, create a simple ILogger interface to decouple your application from NLog directly. This makes it easy to switch loggers later if needed:

public interface ILogger
{
    void Info(string message);
    void Error(string message, Exception exception = null);
    void Warn(string message);
    // Add other log levels as required (Debug, Trace, etc.)
}
Step 2: Implement the NLog Wrapper

Next, build a concrete implementation of ILogger that uses NLog under the hood. This class will initialize the NLog.Logger instance directly:

public class NLogLogger : ILogger
{
    private readonly global::NLog.Logger _nLogInstance;

    // Initialize NLog.Logger using the target type's full name (great for categorizing logs)
    public NLogLogger(Type loggerOwnerType)
    {
        _nLogInstance = global::NLog.LogManager.GetLogger(loggerOwnerType.FullName);
    }

    public void Info(string message)
    {
        _nLogInstance.Info(message);
    }

    public void Error(string message, Exception exception = null)
    {
        if (exception != null)
            _nLogInstance.Error(exception, message);
        else
            _nLogInstance.Error(message);
    }

    public void Warn(string message)
    {
        _nLogInstance.Warn(message);
    }
}
Step 3: Build the Logger Factory

Create a factory interface and implementation to handle creating ILogger instances. This factory is where we'll handle NLog initialization—no Unity resolve calls needed:

public interface ILoggerFactory
{
    ILogger CreateLogger(Type loggerOwnerType);
    ILogger CreateLogger<T>(); // Convenience method for generic types
}

public class NLogLoggerFactory : ILoggerFactory
{
    public ILogger CreateLogger(Type loggerOwnerType)
    {
        // Directly instantiate our NLog wrapper - no Unity Resolve() here!
        return new NLogLogger(loggerOwnerType);
    }

    public ILogger CreateLogger<T>()
    {
        return CreateLogger(typeof(T));
    }
}
Step 4: Set Up Dependency Injection

We'll use Microsoft.Extensions.DependencyInjection (install via NuGet: Install-Package Microsoft.Extensions.DependencyInjection) to wire everything up. This is a lightweight, flexible DI container that works perfectly with Framework 4.6.1.

First, configure the container:

// Initialize the service collection
var services = new ServiceCollection();

// Register our logger factory as a singleton (we only need one instance across the app)
services.AddSingleton<ILoggerFactory, NLogLoggerFactory>();

// Example: Register a business service that needs logging
public class OrderProcessingService
{
    private readonly ILogger _logger;

    // Inject the factory, then create a logger for this specific service
    public OrderProcessingService(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<OrderProcessingService>();
    }

    public void ProcessOrder(int orderId)
    {
        _logger.Info($"Starting processing for order #{orderId}");
        try
        {
            // Your business logic here
        }
        catch (Exception ex)
        {
            _logger.Error($"Failed to process order #{orderId}", ex);
        }
    }
}

// Register your business service (transient, scoped, or singleton based on needs)
services.AddTransient<OrderProcessingService>();

// Build the service provider
var serviceProvider = services.BuildServiceProvider();
Step 5: Configure NLog

Don't forget to add an NLog.config file to your project (set its "Copy to Output Directory" property to "Copy if newer"):

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true">

  <targets>
    <!-- Log to console -->
    <target name="console" xsi:type="Console" layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message}" />
    <!-- Log to rolling file -->
    <target name="file" xsi:type="File" 
            fileName="logs/app-${shortdate}.log"
            layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message} ${exception:format=ToString}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="console,file" />
  </rules>
</nlog>
Why This Works
  • No Unity Dependency: We're not using Unity's LoggerFactory.Resolve() at all—our factory directly creates NLog instances.
  • Decoupling: The ILogger abstraction keeps your business code separate from NLog, making testing and future logger swaps easier.
  • Clean DI Integration: The factory is registered as a singleton, so you get consistent logger creation across your app, and services receive the factory via constructor injection (following DI best practices).
Using the Service

Finally, resolve your service from the container and use it:

var orderService = serviceProvider.GetService<OrderProcessingService>();
orderService.ProcessOrder(123);

内容的提问来源于stack exchange,提问作者user3580768

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:21:30