c# - Mapeo de modelos del mismo tipo para ver instancias
dependency-injection unity3d (4)
He logrado encontrar una opción.
Para cada enemigo:
- Crea el modelo enemigo
- Crea un contexto separado para cada enemigo y almacena el modelo allí.
- Cree un enlace de mediación entre el tipo EnemyView y el tipo EnemyMediator dentro del contexto enemigo.
- Crea la vista del enemigo desde dentro del contexto.
El contexto creará el mediador enemigo y vinculará al modelo enemigo con el mediador enemigo.
La desventaja de esta solución:
- Conduce a muchos contextos, que traen consigo sus propios encuadernadores por inyección, etc.
- Lleva a un uso intensivo de enlaces de contexto cruzado, que potencialmente contaminan ese espacio vinculante. Esto podría solucionarse modificando el contexto para usar una búsqueda jerárquica (que puedo intentar hacer más tarde hoy) antes de buscar en el cuaderno de contexto cruzado.
Estoy usando Extraño COI en mi juego, y estoy teniendo problemas para encontrar cómo asignar vistas a los modelos.
Al inicio del juego, creo varios modelos enemigos. Estos modelos contienen varias estadísticas usadas durante la operación (como cantidades de daños, salud, etc.). Opero estas estadísticas usando Comandos. Luego recorro todos mis modelos en el comando de Inicio y creo las Vistas apropiadas para ellos. Cada EnemyView
tiene un EnemyMediator
, que debe disparar los comandos para el manejo de la inteligencia artificial.
Necesito una forma de decirle a una instancia de View
Model
qué pertenecen. Extraños enlaces de inyección de COI normalmente se distinguen por tipo, o un identificador adicional opcional. Todos mis modelos y vistas enemigos son del mismo tipo, así que tengo que usar este identificador. El problema surge cuando intentamos inyectar las instancias.
Inicialmente traté de dar a cada uno de mis modelos enemigos un GUID, y pasarlo a la View
y el Mediator
, pero el problema luego proviene del hecho de que la inyección Extraña de COI usa criterios de inyección estática. Intentar aplicar mi GUID en los atributos de Inject
genera un error de compilación por razones obvias.
Esto me llevó a usar InjectionBinder.Injector.Inject()
para adquirir enlaces manualmente durante la ejecución de mi Command
usando el GUID. Esto funciona, pero ahora está agregando una dependencia del inyector que no debería necesitar, y esencialmente estoy usando el inyector como un localizador de servicios y estoy perdiendo los beneficios de la inyección.
El problema es que no sé cómo inyectar el modelo específico al que pertenece mi EnemyView
en los comandos que disparo, y por lo tanto estoy atascado con las soluciones del estilo del localizador de servicios.
Como referencia, esto:
es la estructura de la aplicación que estoy tratando de seguir.
Esta no es una solución directa, pero así es como trabajo sobre este tema. Creé un modelo de singleton para todos los enemigos. Este modelo contiene un diccionario donde la clave es la vista.GetInstanceID () y el valor es una clase que contiene las estadísticas para ese enemigo específico.
public class EnemyModel : IEnemyModel
{
// int is the id of the enemy''s instance id in the view i.e. view.GetInstanceID()
public IDictionary<int,Enemy> enemyDict {get;set;}
public EnemyModel ()
{
enemyDict = new Dictionary<int,Enemy>();
}
}
public class Enemy
{
public bool isDangerous = false;
public float health = 1;
}
Tengo el mismo problema para resolver y aquí está la solución que se me ocurrió.
EnemyMediator tiene una refferencia a Enemy (pero no inyectado, incluso puede ser privado). EnemyMediator necesita tener algún modelo de juego singleton que como propiedad enemigo actual;
Ahora cuando creas un enemigo en un comando e instanciaste a un enemigo (Inyectar modelo de juego), primero creas el modelo y lo agregas al valor actual de enemigo del modelo del juego. Ahora crea una instancia de vista.
En el método PostConstruct, lee el valor del valor de CurrentEnemy del juego y lo configura en Mediator.
Cuando disparas una señal / evento, agregas enemigo como parámetro. Ahora el comando tiene información sobre un modelo.
No me gusta agregar el modelo al mediador, pero aún no he encontrado una mejor solución.
Encontré tus mismas dudas y preguntas al tratar de entender dónde encajar mejor dentro de IOC. Entonces, al leer la documentación, leo algo así "los modelos son como objetos de valor (VO)". Así que se me ocurrió esta solución que también usa el potencial de la Unidad. Aquí está mi diseño con un ejemplo:
Creo una clase "EnemyModel" que es un Monobehaviour e implemento una interfaz genérica de IEnemyModel
durante la carga de escena, dentro de StartCommand del contexto, uso AddComponent para agregar un EnemyModel a cada EnemyView. Los datos para cada EnemyModel se cargan desde un archivo o base de datos que describe las propiedades de datos de mi escena.
el mediador tiene una referencia a EnemyView y al EnemyModel (a través de la interfaz)
cuando se envía un comando en el mediador (yo uso señales) el EnemyModel se pasa como un parámetro.
en el comando, tengo una referencia a los datos pasados como un parámetro, por lo que el comando ya conoce los datos con los que trabajar y en realidad está trabajando en el modelo.
Creo que es mejor así que pasar algún tipo de identificación e intentar resolver los datos a través de un administrador de datos más o menos. Además, si EnemyModel es un comportamiento único adjunto al objeto de juego EnemyView es más fácil depurar sus valores del editor.
¿Qué piensas?