Je sais que la même question a été posée à plusieurs reprises (par exemple: ici, ici,ici et ici), mais c'était pour les versions précédentes de l'Unité où la réponse était à la charge sur LifetimeManager
classe.
La Documentation dit:
L'unité utilise des types spécifiques qui héritent à partir de la LifetimeManager de la classe de base (collectivement, la durée de vie les gestionnaires) pour contrôler la façon dont il stocke les références à des instances d'objet et comment le conteneur dispose de ces les instances.
Ok, ça sonne bien donc j'ai décidé de vérifier la mise en œuvre de la construire dans la durée de vie des gestionnaires. Ma conclusion:
-
TransientLifetimeManager
- pas de manipulation de l'élimination. Conteneur ne résout instance et il n'a pas le suivre. Code appelant est responsable de l'élimination de l'instance. -
ContainerControlledLifetimeManager
- dispose d'instance lorsque la durée de vie du gestionnaire est éliminé (= lorsque le récipient est disposé). Fournit de l'instance du singleton partagée entre tous les conteneurs dans hiérarchique. -
HierarchicalLifetimeManager
- dérive de comportement d'ContainerControlledLifetimeManager
. Il fournit un "singleton" instance par conteneur dans hiérarchique (sous-conteneurs). -
ExternallyControlledLifetimeManager
- pas de manipulation de l'élimination. Comportement Correct parce que le conteneur n'est pas propriétaire de l'instance. -
PerResolveLifetimeManager
- pas de manipulation de l'élimination. Il est généralement la même queTransientLifetimeManager
, mais il permet la réutilisation de l'instance pour l'injection de dépendances lors de la résolution d'ensemble de l'objet graphique. -
PerThreadLifetimeManager
- pas de manipulation de disposer comme il est également décrite dans MSDN. Qui est responsable de l'élimination?
La mise en œuvre de build- PerThreadLifetimeManager
est:
public class PerThreadLifetimeManager : LifetimeManager
{
private readonly Guid key = Guid.NewGuid();
[ThreadStatic]
private static Dictionary<Guid, object> values;
private static void EnsureValues()
{
if (values == null)
{
values = new Dictionary<Guid, object>();
}
}
public override object GetValue()
{
object result;
EnsureValues();
values.TryGetValue(this.key, out result);
return result;
}
public override void RemoveValue()
{ }
public override void SetValue(object newValue)
{
EnsureValues();
values[this.key] = newValue;
}
}
Donc conteneur d'élimination ne pas jeter jetables instances créées avec cette vie de gestionnaire. Fil d'achèvement permettra également de ne pas disposer de ces instances. Alors, qui est chargé de libérer les instances?
J'ai essayé manuellement éliminer résolu exemple dans le code et j'ai trouvé un autre problème. Je ne peux pas le démontage de la instnace. RemoveValue de la durée de vie de manager est vide - une fois que l'instance est créée, il n'est pas possible de le supprimer à partir du fil de dictionnaire statique (je suis aussi méfiant qu' TearDown
méthode ne fait rien). Donc, si vous appelez Resolve
après l'élimination de l'instance, vous obtiendrez éliminés de l'instance. Je pense que cela peut être assez gros problème lors de l'utilisation de cette vie avec le gestionnaire de threads du pool de threads.
Comment utiliser correctement cette vie manager?
En outre, cette mise en œuvre est souvent réutilisé dans la coutume durée de vie des gestionnaires comme PerCallContext, PerHttpRequest, PerAspNetSession, PerWcfCall, etc. Seul thread dictionnaire statique est remplacé avec quelques autres construire.
Aussi dois-je comprends bien que la manipulation jetables objets dépend de la durée de vie de gestionnaire? Ainsi, le code de l'application est dépendante de la durée de vie utilisé manager.
J'ai lu que dans d'autres conteneurs IoC traitant temporaire jetable objets est gérée par les sous-conteneurs, mais je n'ai pas trouver d'exemple de l'Unité - il pourrait être probablement manipulés avec local étendue de sous-conteneur et HiearchicalLifetimeManager
mais je ne suis pas sûr de savoir comment faire.