Estoy usando ASP.NET Núcleo, sé que tal mecanismo de Registro ya está previsto por el marco, pero el uso de este para ilustrar mi problema.

Yo estoy usando el tipo de patrón de Fábrica para construir el Registrador de clase, ya que no sé el tipo de registro (porque se almacena en la base de datos).

La ILogger Contrato

Log(string msg)

Luego LoggerFactory devolverá un ILogger después de la creación de un registro basado en el parámetro pasado de DB:

public class LoggerFactory
{
    public static Contracts.ILogger BuildLogger(LogType type)
    {
        return GetLogger(type);
    }

//other code is omitted, GetLogger will return an implementation of the related logger

Ahora, cuando tengo que usar el Registrador tengo que hacerlo de esta forma:

  public class MyService
{
    private ILogger _logger
    public MyService()
    {
        _logger = LoggerFactory.BuildLogger("myType");
    }

Pero, tengo la intención de mantener mis clases sin ningún tipo de instanciación, necesito usar Constructor DI en MyService y necesito inyectar todas las dependencias de Inicio:

    services.AddTransient<Contracts.ILogger, LoggerFactory.BuildLogger("param") > ();

Pero esto no va a funcionar esto tenemos que pasar de una aplicación concreta.
Cómo hacer que funcionan con DI, ¿hay una mejor enfoque para su implementación?

  • Una opción es la inyección de la LoggerFactory, en lugar de un ILogger. De esta manera, se obtiene la LoggerFactory, obtener el Tipo de tu DB y construir su ILogger. Si usted desea inyectar el ILogger usted tendría que saber el Tipo de su ILogger en el momento de la inyección. Pero puede que no tenga esta información todavía.
  • Te refieres a pasar el LoggerFactory en MyService Constructor y no añadir a la .net core services
  • Sí. Como este: services.AddSingleton<LoggerFactory>();. Singleton significa que usted va a crear un LoggerFactory objeto sólo en la primera vez que lo necesite. Después de esto, tendrás que usar sólo la misma. A continuación, utilice como este: public MyService(LoggerFactory loggerFactory) {....}

1 Comentario

  1. 16

    Hay un par de errores en su planteamiento:

    Lugar, el servicio debería ser como sigue:

    public class MyService
    {
        private ILogger _logger;
        public MyService(ILogger logger)
        {
            _logger = logger;
        }
    }

    Esto simplifica enormemente a todos los consumidores que dependen de ILogger. Esto también significa que obtener el derecho ILogger para MyService se convierte en una responsabilidad de la La Composición De La Raíz, que es el lugar correcto para tener este conocimiento.

    No significa sin embargo que usted puede ser que necesite para alejarse de la incorporada en el contenedor de DI de ASP.NET el Núcleo de una de las características más ricos DI la biblioteca, debido a la incorporada en el contenedor no es capaz de hacer de un contexto, conscientes de registro para ILogger, mientras que tiene la biblioteca de auto-alambre otros constructor dependencias así.

    Con el ASP.NET Núcleo DI contenedor, puede sólo de la mano de alambre de sus servicios el uso de un delegado. Por ejemplo:

    services.AddTransient<MyService>(c => new MyService(
        BuildLogger(typeof(MyService).Name),
        c.GetRequiredService<ISomeOtherDependency>(),
        c.GetRequiredService<IYetAnotherOne>());
    • Steven, con su ejemplo, él no puede inyectar la correcta ILogger, ¿verdad? Si conoce el tipo antes de crear instancias de MyService, entonces él puede cambiar el constructor para public MyService(ILogger<TypeA> logger). Pero ya que él no sabe de eso, él debe inyectar una interfaz que puede hacer eso por él. Me corrija si estoy equivocado.
    • No estoy seguro de que yo te siga. Además de esto, yo no aconsejaría a la introducción de un genérico de abstracción de aquí, porque MyService es completamente desinteresado en este tipo genérico; sólo se quiere registrar. Por lo tanto, es un problema de la Composición de la Raíz de suministrar el tipo correcto, no del consumidor.
    • Entiendo que esto no es factible con ASP Núcleo DI Contenedor ya que no proporcionan la Composición de la Raíz? Si la respuesta fue Sí, ¿cómo hacer que el uso de otras Librerías como Ninject o AutoFac?
    • Cada aplicación contiene una Composición de la Raíz. Mejor es ocultar el marco del ILogger abstracción detrás de una aplicación específica de la abstracción, como se describe aquí e implementar un adaptador a la SEÑORA Extensiones.El registro como se describe aquí. Esta documentación, explica como conectar este adaptador Simple usando un Inyector. Si usted va a tener a Google si quieres saber cómo conectar esta usando Ninject o Autofac.
    • Definitivamente estoy de acuerdo con lo que están diciendo y muy gracias a tus explicaciones claras. Pero, Si quiero utilizar la DI, me gustaría pasar a la Interfaz y la implementación en el contenedor. Sin embargo, en mi caso no sé la Aplicación ya que es un parámetro db. Esto significa que sólo tengo una manera de hacer esto , por escrito, `si else’ comprobar el db param tipo y, a continuación, pasar a la aplicación concreta. Si hay otra manera de hacerlo, por favor hágamelo saber.
    • Usted no debe construir su objeto de gráficos basados en datos en tiempo de ejecución, así como usted no debe construir componentes de uso de datos en tiempo de ejecución. En lugar de crear un proxy de aplicación para su ILogger abstracción que puede llamar a la base de datos y enviar la llamada a la implementación real. De esta manera usted puede agregar esta sin la complicación de los consumidores de ILogger y evitar complicar la Composición de la Raíz.
    • Puede usted por favor proporcione Pseudo código para esta o cualquier ejemplo
    • OK, voy a publicar otra pregunta y vincularlo a una con mi código real.
    • Me preguntó de nuevo la pregunta y vinculado a este.
    • si entiendo tu idea, la ILogger proxy haría el trabajo de la fábrica, sin que el consumidor lo sepa, ¿verdad? Así, el consumidor todavía dependen de ILogger (en lugar de ILoggerFactory), e internamente el proxy de la llamada a la adecuada concreto ILogger. Que suena mucho mejor que hacer que los consumidores depender de algún tipo de ILoggerFactory.

Dejar respuesta

Please enter your comment!
Please enter your name here