ServiceStack IOC. AutoWire(esto) intenta inyectar propiedades públicas que no están registradas en el Container

Al utilizar ServiceStack y su marco IoC/DI, tengo el siguiente problema:

El marco DI inyecta nulo en una propiedad, y ese tipo de propiedad no está registrado en el contenedor.

class DependencyInjectedA : IDependencyInjectedA
{
    public DependencyInjectedB { get; set; }
}

class DependencyInjectedB 
{
    public Dictionary MyProperty { get; set; }
}

Y en mi método Configure:

public override void Configure(Container container)
{
    base.Configure(); // here we have code like 'Container.AutoWire(this);'
    container.AddSingleton();
    container.AddSingleton();
}

Así que, en la clase de padres, yo sí.

Container.AutoWire(this);

y la razón detrás de la llamada AutoWire es para que pueda conseguir el marco DI para inyectar a los descendientes de this. Estaba bajo la impresión de que sólo los tipos registrados en el Container serían de dependencia inyectada, y también que sería descendiente de this, pero parece que también MyProperty dentro DependencyInjectedB se inyecta, y luego con un null valor, ya que no hemos añadido Dictionary al Contenedor.

Aquí hay una imagen (algo editado) de lo que sucede: el DI inyecta NULL, cuando creo que no debería hacerlo.

enter image description here

Mythz en realidad dice que aquí:

Registro automático Puedes registrar dependencias para que todas las las dependencias son automáticamente autopropulsadas. Como los hooks arriba, una vez resuelta Funq creará una nueva instancia resolviendo dependencias para el constructor que tiene los más argumentos, así como todo público propiedades.

Preguntas:

  • ¿Cómo puedo entonces tener propiedades públicas que no quiero ser inyectada?
  • ¿Hay una manera de inyectar sólo los tipos que se registran en el contenedor (.AddXXX)?

Pregunta hecha hace 3 años, 5 meses, 0 días - Por binarymaestro


3 Respuestas:

  • Este es el comportamiento de Funq Autowiring que hace tanto propiedad pública como la inyección de constructor.

    Específicamente el comportamiento de autoaspiración de Funq inyectará cualquier propiedad que son:

    • público
    • writable (es decir, tiene una fuente pública)
    • No es un ValueType o cuerda
    • Su nombre completo no está registrado en Container.IgnorePropertyTypeFullNames colección

    Así que si no quieres que las propiedades inyectadas no pueden cumplir todos los criterios anteriores. Si es sólo una propiedad Tipo que desea prevenir la inyección, puede registrar el nombre completo en:

    Container.IgnorePropertyTypeFullNames.Add(typeof(DependencyInjectedB).FullName);
    

    Alternativamente cambiarlo así que no es public, de lo contrario no deberías usar APIs AutoWiring de Funq que contiene este comportamiento, usted registraría la dependencia usando una función de fábrica personalizada, por ejemplo:

    container.AddSingleton(c => new DependencyInjectedA());
    

    Respondida el Dec 17, 2020 a las 10:49 - por syntaxsniper

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando se debe a que al llamar a Container.AutoWire(this) estás permitiendo que ServiceStack IoC intente inyectar todas las propiedades públicas de tus clases que no están registradas en el contenedor.

    Para evitar que ServiceStack IoC intente inyectar propiedades que no están registradas en el contenedor, puedes seguir algunas opciones:

    • Evitar la llamada a `Container.AutoWire(this)`: Puedes evitar la llamada a `Container.AutoWire(this)` y en su lugar registrar manualmente todas las dependencias que deseas inyectar en el contenedor. Esto te da un mayor control sobre qué dependencias se inyectan y permite evitar que se inyecten dependencias no deseadas.
    csharp
    public override void Configure(Container container)
    {
        base.Configure(); 
        container.AddSingleton();
        container.AddSingleton();
        // Registrar otras dependencias necesarias aquí
    }
    

    • Utilizar atributos de ServiceStack para controlar la inyección:
    Puedes usar atributos como [Required] o [AutoWired] en tus propiedades para controlar si deseas que se inyecten o no. Por ejemplo, puedes marcar la propiedad DependencyInjectedB con [AutoWired(false)] para evitar que se intente inyectar:

    csharp
    class DependencyInjectedA : IDependencyInjectedA
    {
        [AutoWired(false)]
        public DependencyInjectedB DependencyInjectedB { get; set; }
    }
    

    Estas son algunas formas en las que puedes controlar qué propiedades se inyectan en tus clases cuando utilizas el IoC de ServiceStack. Espero que esta información te sea útil.

    Respondida el Dec 18, 2020 a las 10:52 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Preguntas y respuestas:

    1. ¿Cómo puedo entonces tener propiedades públicas que no quiero ser inyectadas?

    Para evitar que una propiedad pública sea inyectada, puedes utilizar el atributo [IgnoreDependency] en la propiedad. Esto le indicará al marco IoC que no debe inyectar la propiedad.

    2. ¿Hay una manera de inyectar sólo los tipos que se registran en el contenedor (.AddXXX)?

    Sí, puedes utilizar el método Register<T> para registrar explícitamente los tipos que deseas inyectar. Esto evitará que el marco IoC inyecte cualquier otro tipo que no esté registrado.

    Código actualizado:

    csharp
    public override void Configure(Container container)
    {
        base.Configure(); // aquí tenemos código como 'Container.AutoWire(this);'
        container.Register();
        container.Register();
    }
    

    Propiedades que no deben ser inyectadas:

    csharp
    [IgnoreDependency]
    public Dictionary MyProperty { get; set; }
    

    Inyección manual de propiedades:

    Si deseas inyectar manualmente ciertas propiedades en lugar de utilizar la inyección automática, puedes utilizar el método Inject del contenedor:

    csharp
    container.Inject(this, includePublicFields: true); // inyecta todas las propiedades públicas, incluidas las no registradas
    

    Recomendaciones adicionales:

    Registra siempre explícitamente los tipos que desees inyectar para evitar confusiones y posibles errores. Utiliza el atributo [IgnoreDependency] para las propiedades que no deben inyectarse. * Considera utilizar una biblioteca de inyección de dependencias de terceros para una mayor flexibilidad y control sobre el proceso de inyección.

    Respondida el Dec 18, 2020 a las 10:57 - por Gemini

    Votos positivos: 0 | Votos negativos: 0