c# 4.0 - SimpleIoc: ¿puede proporcionar una nueva instancia cada vez que sea necesario?
c#-4.0 mvvm (3)
Después de luchar con SimpleIoC para proporcionar nuevas instancias cada vez que se solicita un tipo específico y descubrir esta característica no se implementa (el método basado en claves aceptado anteriormente no se ajusta a los escenarios en los que desea decir, realiza una operación de base de datos y lanza la conexión de distancia cada vez), se me ocurrió una solución relativamente decente que combina IoC con el patrón Factory: crear una clase que asuma la responsabilidad de instanciar nuevas instancias de un cierto tipo a través de una función:
class MyObjectFactory: IMyObjectFactory
{
public MyObject CreateObject()
{
return new MyObject();
}
}
Cree la interfaz para la clase de fábrica MyObject:
public interface IMyObjectFactory
{
MyObject CreateObject();
}
A continuación, configure el contenedor IoC para proporcionar la fábrica a cualquier clase que use instancias de MyObject:
SimpleIoc.Default.Register<IMyObjectFactory, MyObjectFactory>();
Ahora, cualquier clase que requiera una nueva instancia de MyObject declarará su requisito MyObjectFactory (en lugar del requisito de MyObject) en el constructor para la inyección del constructor:
public class MyObjectUser
{
MyObject _myObject;
public MyObjectUser(IMyObjectFactory factory)
{
_myObject = factory.CreateObject();
}
}
De esta manera, creo que no está sujeto a las limitaciones del patrón Factory y tiene todos los beneficios de los contenedores IoC y Constructor Injection, eludiendo también las limitaciones de SimpleIoC.
Por lo que yo entiendo, SimpleIoc usa el método GetInstance para recuperar una instancia de una clase que está registrada. Si la instancia no existe, la creará. Sin embargo, esta instancia se almacena en caché y siempre se recupera, lo que imita el patrón singleton.
Mi opinión es que no es necesario mantener una instancia de ViewModel en una memoria si hay una pequeña posibilidad de que este ViewModel sea necesario dos veces, por lo que me gustaría crear una nueva instancia cada vez que sea necesario. Si tenemos una fábrica para ViewModels, tendremos una propiedad como esta:
public MyViewMOdel MyViewModel
{
get { return SimpleIoc.Default.GetInstance<MyViewModel>(); }
}
este usa un patrón singleton, que creo que no es la mejor práctica en todos los casos. Para eludir este problema, hago esto:
public MyViewModel MyViewModel
{
get { return new MyViewModel(SimpleIoc.Default.GetInstance<ISomeInterface>()); }
}
Éste tiene la desventaja de que si alguna vez cambio un constructor para MyViewModel, también tendré que actualizar esta propiedad. No es gran cosa, pero aún hay algún tipo de dependencia.
¿Cómo manejas este escenario y hay algo que me falta? y por qué se decidió no devolver una instancia no compartida.
Y otra cuestión es que, en la sesión de inmersión en profundidad de MVVM, Laurent usa el método GetInstance inmediatamente después de que registra un ViewModel particular, para asegurar, como él dice, que ya hay una instancia de este ViewModel en el contenedor. ¿Por qué es exactamente esto necesario? Si está buscando un ViewModel a través de ViewModelLocator, lo creará siempre que sea necesario. Entonces, ¿por qué querría tenerlos creados por adelantado?
Puede obtener una instancia diferente cada vez al pasar una clave diferente al método GetInstance. Sin embargo, las instancias se almacenarán en caché, por lo que si no desea mantenerlas en la memoria caché, deberá llamar a Anular el registro con la clave correspondiente.
En la demostración, estaba creando la VM por adelantado porque MainVM estaba enviando mensajes a SecondaryVM. Dado que el registro en el Messenger se realiza en el constructor de SecondaryVm, debe crearse antes de que pueda comenzar a recibir mensajes. El Messenger es genial porque está muy desacoplado, pero es uno de estos casos en los que necesita hacer un trabajo extra para compensar el desacoplamiento: el SecondaryVM es el objetivo de los mensajes, aunque MainVM no obtiene ninguna referencia al mismo.
Espero que tenga sentido. Saludos, Laurent
SimpleIOC es lo que es ... un contenedor simple de COI. Tendrá algunas deficiencias ... pero no está obligado a hacerlo, siempre podrá usar otro contenedor ICO (por ejemplo, Unity, Autofac, Castle, ...).
Como Laurent afirma que modeló su SimpleIOC en este contenedor . También menciona este contenedor como fuente de su inspiración.
Sin embargo, recuerde que no está obligado a usar un contenedor específico con MVVM . En varios de mis proyectos utilicé Unity, pero todos los otros contenedores de IOC lo harán igualmente bien, es una cuestión de requisitos, preferencias del cliente y, si todo lo demás falla, un simple gusto personal .