unity tamaño tag posicion obtener objetos objeto instantiate instanciar generar destruir cambiar aleatorios c# unity-container ioc-container instance registering

c# - tamaño - unity destroy gameobject



Cómo eliminar(anular el registro) instancia registrada de la asignación de Unity (6)

Aquí es cómo manejé las instancias de eliminación de registro de un contenedor de unidad

Necesitaba implementar la funcionalidad Agregar / Eliminar como esta:

public interface IObjectBuilder { void AddInstance<T>(T instance); void RemoveInstance<T>(T instance); }

Creé un administrador de por vida personalizado para hacer la implementación

public class ExplicitLifetimeManager : LifetimeManager { object Value; public override object GetValue() { return Value; } public override void SetValue(object newValue) { Value = newValue; } public override void RemoveValue() { Value = null; } }

Aquí está la implementación final:

Dictionary<object, ExplicitLifetimeManager> Instances = new Dictionary<object, ExplicitLifetimeManager>(); public void AddInstance<T>(T instance) { ExplicitLifetimeManager e = new ExplicitLifetimeManager(); Instances[instance] = e; Container.RegisterInstance(instance, e); } public void RemoveInstance<T>(T instance) { Instances[instance].RemoveValue(); Instances.Remove(instance); }

invocar removevalue en el administrador de por vida personalizado hace que la instancia no se registre

Me encuentro con un problema que no puedo resolver ahora. Tengo lo siguiente:

UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance);

donde UnityHelper.DefaultContainer es mi ayudante para obtener el contenedor de unidad con la configuración cargada.

aquí IMyInterface instance como una instancia de IMyInterface .

Entonces, en cualquier lugar (algún tiempo después del uso), quiero eliminar esta asignación. Eliminarlo en absoluto. ¿Cómo puedo hacerlo?

Yo he tratado:

UnityHelper.DefaultContainer.Teardown(instance)

pero no fue exitoso y el siguiente código devuelve la instance todos modos:

UnityHelper.DefaultContainer.ResolveAll<IMyInterface>()


Creo que eso es lo que estás buscando.

var lifetimeManager = new TransientLifetimeManager(); UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance, lifetimeManager); lifetimeManager.RemoveValue();


Esta es una pregunta antigua, pero algunas respuestas son engañosas, por lo que proporcionaré la mía. No puedes hacer eso con Unity. El final de la historia. Llamar a RemoveValue en los administradores de registros de por vida no logra anular el registro ( más información sobre los administradores de por vida ), y ese método no tiene la intención de anular el registro de nada. Entonces, el comportamiento final es inesperado y no es conveniente. Por supuesto, RemoveValue tiene aún menos sentido si registra una implementación o un método de fábrica, aunque la pregunta es sobre anular el registro de instancias. Considere la siguiente pieza de código

public interface SomeInterface { int Foo { get; set; } } public class SomeImplementation: SomeInterface { public int Foo { get; set; } } static void Main(string[] args) { UnityContainer iocContainer = new UnityContainer(); string registerName = "instance"; //before any registration Resolve<SomeInterface>(iocContainer, registerName); iocContainer.RegisterInstance<SomeInterface>(registerName, new SomeImplementation()); //after registration Resolve<SomeInterface>(iocContainer, registerName); ClearValue<SomeInterface>(iocContainer, registerName); //after clear value Resolve<SomeInterface>(iocContainer, registerName); } private static void Resolve<T>(UnityContainer iocContainer,string name) { if (iocContainer.IsRegistered<T>(name)) iocContainer.Resolve<T>(name); iocContainer.ResolveAll<T>(); } private static void ClearValue<T>(UnityContainer iocContainer, string name) { foreach (var registration in iocContainer.Registrations.Where(p => p.RegisteredType == typeof(T) && p.Name==name)) { registration.LifetimeManager.RemoveValue(); } }

Si lo depura, verá que después de la llamada a ClearValue , el contenedor aún dice que está registrado, pero si intenta resolver esa instancia lanzará una excepción. Lo que es aún peor, las llamadas a ResolveAll<T> también fallarán.

En ClearValue , no importa si lo hace ClearValue , envuelve su instancia de registro con otro IoC o una clase personalizada, o proporciona su propio LifeTimeManager, ResolveAll<T> e IsRegistered<T> no se comportarán como se esperaba, y el registro se realizará todavía estar allí. Así que no lo intentes porque no funcionará y causará problemas en el futuro.


Tenía un requisito similar por el cual quería almacenar temporalmente los objetos en el contenedor de la unidad y descubrí que esto no era posible (o al menos era posible). Si su objetivo es tener un lugar de almacenamiento temporal fácilmente disponible para la unidad, cree un servicio de almacenamiento temporal.

public class TemporaryStorageService : ITemporaryStorageService { public void Deposit<T>(Object o, string key) { System.Windows.Application.Current.Properties[key] = o; } public T Withdraw<T>(string key) { T o = (T)System.Windows.Application.Current.Properties[key]; System.Windows.Application.Current.Properties.Remove(key); return o; } }

Registre su servicio con Unity. Luego, cuando desee almacenar un objeto, llame al Método de depósito y cuando desee eliminar el objeto, llame al método Retirar. Una explicación más completa se puede encontrar aquí


Tengo el mismo desafío y después de experimentarlo lo resolví utilizando el ContainerControlledLifetimeManager estándar y llamando a RemoveValue cuando quiero eliminar la instancia del contenedor. Tenga en cuenta que si no está utilizando interfaces y su objeto tiene un constructor que el contenedor puede encontrar y usar, recreará la instancia una vez que la haya destruido con lifetimeManager.RemoveValue ().

[TestClass] public class UnityContainerTest { [TestMethod] public void RemoveFromContainer() { UnityContainer container = new UnityContainer(); MyUnityMember member = new MyUnityMember(5); LifetimeManager lifetimeManager = new ContainerControlledLifetimeManager(); container.RegisterInstance(member, lifetimeManager); var resolved = container.Resolve<MyUnityMember>(); Assert.IsNotNull(resolved); lifetimeManager.RemoveValue(); try { resolved = container.Resolve<MyUnityMember>(); Assert.Fail(resolved + " is still in the container"); } catch (ResolutionFailedException) { } } public class MyUnityMember { public MyUnityMember(int x) { I = x; } public int I { get; private set; } } }


Tuve el mismo problema y simplemente eliminé los registros del ContainerControlledLifetimeManager de mi Container :

foreach (var registration in container.Registrations .Where(p => p.RegisteredType == typeof(object) && p.LifetimeManagerType == typeof(ContainerControlledLifetimeManager))) { registration.LifetimeManager.RemoveValue(); }