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.

Equivalentes de las invocaciones de .Register en Simple Injector

Tengo un objeto cuyo constructor requiere un primitivo. Lo registro usando un delegado (por favor, excuse el ejemplo ficticio).

container.Register<account>(() => new Account(1000M), Lifestyle.Singleton);

Registro este tipo Account como la implementación de una interfaz IAccount. Al hacerlo utilizando la llamada marcada como B a continuación, .Verify() de SimpleInjector muestra el siguiente mensaje de error:

/* B */container.Register<iaccount, account="">(Lifestyle.Singleton);

El constructor del tipo Account contiene el parámetro ‘funds’ de tipo decimal, que no se puede utilizar para la inyección de constructor porque es un tipo de valor. (Parámetro ‘TImplementation’)

El uso de la llamada marcada como A en su lugar no tiene este problema y funciona como se esperaba:

/* A */container.Register<iaccount>(() => container.GetInstance<account>(), Lifestyle.Singleton);

Parece que asumí incorrectamente que A y B serían efectivamente equivalentes. ¿Qué me he perdido? ¿Por qué B no utiliza el delegado registrado para la creación de la instancia de Account? Gracias.

A continuación se muestra un archivo en formato LINQPad (.linq):
“`csharp
<query kind="Program">
<nugetreference>SimpleInjector</nugetreference>
<namespace>SimpleInjector</namespace>
</query>

void Main()
{
var containerRegistry = new ContainerRegistry();
Console.WriteLine("Balance = " + containerRegistry.GetInstance<account>().Balance);
}

public class ContainerRegistry
{
private readonly Container container = new Container();

<pre><code>public ContainerRegistry()
{
container.Register<account>(() => new Account(1000M), Lifestyle.Singleton);

/* A */container.Register<iaccount>(() => container.GetInstance<account>(), Lifestyle.Singleton);
/* B */container.Register<iaccount, account="">(Lifestyle.Singleton);

container.Verify();
}

[Obsolete] public TInstanceType GetInstance<tinstancetype>() where TInstanceType : class
=> container.GetInstance<tinstancetype>();
</code></pre>

}

public class Account : IAccount
{
public decimal Balance => funds;

<pre><code>private readonly decimal funds;

public Account(decimal funds)
{
this.funds = funds;
}
</code></pre>

}

public interface IAccount
{
decimal Balance { get; }
}
“`</iaccount,></iaccount,>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema al registrar IAccount utilizando la llamada marcada como B es que SimpleInjector intenta crear una instancia de Account directamente, sin utilizar el delegado registrado para crear instancias de Account. Esto ocurre porque en la llamada B, SimpleInjector está diciéndole al contenedor que Account es la implementación de IAccount, y que debería ser capaz de crear una instancia de Account sin más orientación. Sin embargo, como Account requiere un parámetro primitivo en su constructor, SimpleInjector no sabe cómo obtener el valor para este parámetro, y por lo tanto falla.

    Por otro lado, al utilizar la llamada marcada como A, SimpleInjector crea una instancia de IAccount obteniendo primero una instancia de Account utilizando el delegado registrado, y luego realizando un casting a IAccount. De esta manera, el delegado se utiliza correctamente para obtener el valor necesario del parámetro primitivo para crear Account.

    En resumen, mientras que tanto A como B registran efectivamente Account como la implementación de IAccount, solo A garantiza que el delegado registrado para crear instancias de Account se utilice al crear instancias de IAccount.

Comments are closed.