C'est une vieille question, mais certaines réponses sont trompeuses, donc je vais donner mon propre. Vous ne pouvez pas faire cela avec Unity. Fin de l'histoire. En appelant RemoveValue
sur les enregistrements, les gestionnaires de durée de vie n'obtiennent pas l'annulation de l'enregistrement (more information about lifetime managers), et cette méthode n'est pas destinée à annuler l'inscription. Donc, le comportement final est inattendu et pas pratique. Bien sûr, RemoveValue
a encore moins de sens si vous enregistrez une implémentation ou une méthode d'usine, bien que la question concerne les instances de désinscription. Considérons le prochain morceau de code
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 vous le débogage, vous verrez que, après l'appel à ClearValue
, le conteneur dit encore il est enregistré, mais si vous essayez de résoudre ce cas, il lancera une exception . Ce qui est encore pire, les appels à ResolveAll<T>
échoueront aussi.
En somme, peu importe si vous faites ClearValue
, enrouler autour de votre instance de registre avec un autre IoC ou une classe personnalisée, ou fournir votre propre LifeTimeManager, ResolveAll<T>
et IsRegistered<T>
se comportent ne le ferai pas comme prévu, et l'enregistrement sera toujours Là. Donc, ne l'essayez pas parce que ça ne marchera pas et cela causera des problèmes sur la route.
Intéressant. Pourquoi en avez-vous besoin d'ailleurs? –
J'utilise des instances simulées dans les tests et je veux effacer l'environnement pour le prochain test. Actuellement, les instances du test précédent se trouvent dans le conteneur et apparaissent lorsque j'appelle ResolveAll(). –
bug0r
Dans le scénario Commmon, le développeur peut modifier l'implémentation à la volée. – bug0r