es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Uso de Serilog WCF sin constructores?

Soy nuevo en c# y estoy tratando de usar Serilog en una aplicación de WCF. Esta aplicación de WCF está alojada en IIS 6.0.

Necesito crear el registrador solo una vez cuando se inicializa el servicio. Sin embargo, parece que WCF no tiene constructores. ¿Cómo puedo crear el registrador a continuación solo una vez y tenerlo disponible para el resto de la aplicación? Se agradecerían ejemplos de código.

ILogger logger = new LoggerConfiguration()
                      .ReadAppSettings()
                      .CreateLogger();
Log.Logger = logger;

Pensé en usar AppInitialize en la carpeta App_Code, pero no parece que el programa active el método AppInitialize.

public class InitializeApp
{
    public static void AppInitialize()
    {
        ILogger logger = new LoggerConfiguration()
                              .ReadAppSettings()
                              .CreateLogger();
        Log.Logger = logger;
    } 
}

Cuando ejecuto el proyecto en Visual Studio 2019, nunca se activa AppInitialize.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para crear el registrador Serilog solo una vez cuando el servicio WCF se inicializa, puedes aprovechar el ciclo de vida del servicio WCF. Específicamente, puedes usar el evento Opening de ServiceHost para crear el registrador antes de que el servicio se inicie. Aquí tienes un ejemplo:

    public class MyService : IMyService
    {
        private readonly ILogger _logger;
    
        public MyService()
        {
            // el registrador será inyectado por el contenedor (por ejemplo, Autofac)
            _logger = Log.Logger;
        }
    
        // métodos del servicio WCF...
    }
    
    public class MyServiceHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            var host = new ServiceHost(serviceType, baseAddresses);
    
            // crear el registrador cuando se está abriendo el host del servicio
            host.Opening += (sender, args) =>
            {
                Log.Logger = new LoggerConfiguration()
                    .ReadFrom.AppSettings()
                    .CreateLogger();
            };
    
            return host;
        }
    }
    

    En este ejemplo, se crea el ServiceHost con una clase ServiceHostFactory personalizada que anula el método CreateServiceHost. La instancia de ServiceHost se crea con una referencia al tipo de servicio (MyService) y las direcciones base para el servicio.

    En el método CreateServiceHost, se agrega un controlador de eventos al evento Opening de ServiceHost. Este evento se activa cuando el host del servicio se está iniciando. En el controlador de eventos, se crea el registrador Serilog utilizando la configuración del LoggerConfiguration desde la configuración de la aplicación y se asigna a la propiedad estática Log.Logger.

    En la clase MyService, el registrador se inyecta a través del constructor, por lo que estará disponible para todos los métodos de la clase.

    Recuerda actualizar el archivo web.config con la factory correcta para el host del servicio:

    <system.servicemodel>
      <servicehostingenvironment multiplesitebindingsenabled="true">
        <serviceactivations>
          <add service="MyService" factory="MyServiceHostFactory" relativeaddress="MyService.svc"></add>
        </serviceactivations>
      </servicehostingenvironment>
    </system.servicemodel>
    

    Espero que esto ayude. Hazme saber si tienes alguna pregunta.

Comments are closed.