L'Unité peut être faite de ne pas jeter SynchronizationLockException tout le temps?
L'Unité conteneur d'injection de dépendance a ce qui semble être largement un problème connu où la SynchronizedLifetimeManager sont souvent la cause de la Surveiller.La sortie de la méthode de jeter une SynchronizationLockException qui est ensuite capturé et ignoré. C'est un problème pour moi parce que je tiens à déboguer avec Visual Studio définie sur arrêt sur toute la levée d'une exception, de sorte que chaque fois que mon application démarre, je suis en rupture sur cette exception à plusieurs reprises sans raison.
Comment puis-je éviter cette exception d'être jeté?
Partout où cela est mentionné ailleurs sur le web, de l'avis implique généralement de changer les paramètres du débogueur de l'ignorer. Cela s'apparente à aller chez le médecin et en disant: "docteur, Docteur, mon bras me fait quand je lève," n'être dit, "eh Bien, arrêtez de le soulever." Je suis à la recherche d'une solution qui s'arrête à l'exception levée dans la première place.
L'exception se produit dans la méthode SetValue parce qu'il fait l'hypothèse que GetValue auront été appelé en premier, où Moniteur.Entrez est appelé. Cependant, la LifetimeStrategy et UnityDefaultBehaviorExtension classes à la fois régulièrement appel SetValue sans appel GetValue.
Je préfère ne pas avoir à modifier le code source et de maintenir ma propre version de l'Unité, donc je suis en espérant une solution où je peux ajouter une combinaison des extensions, des politiques, des stratégies ou le conteneur qui fera en sorte que, si la durée de vie manager est un SynchronizedLifetimeManager, GetValue est toujours appelée avant toute autre chose.
Vous devez vous connecter pour publier un commentaire.
Je suis sûr qu'il ya beaucoup de façons de code pourrait appeler SynchronizedLifetimeManager, ou d'un descendant comme ContainerControlledLifetimeManager, mais il y avait deux scénarios, en particulier, qui ont été me causer des problèmes.
La première était de ma faute - j'ai été en utilisant le constructeur de l'injection de fournir une référence au conteneur, et dans ce constructeur, j'ai été également l'ajout de la nouvelle instance de la classe pour le conteneur pour une utilisation future. Cette rétro approche ayant pour effet de modifier la durée de vie du gestionnaire de Transitoire à ContainerControlled de sorte que l'objet de l'Unité appelée GetValue n'était pas le même objet, qu'il appelle SetValue sur. La leçon est ne rien faire pendant la phase de construction qui pourrait changer la vie de l'objet gestionnaire.
Le deuxième scénario, c'est que chaque fois RegisterInstance est appelé, UnityDefaultBehaviorExtension appels SetValue sans appel GetValue premier. Heureusement, l'Unité est suffisamment extensible que, avec assez sanglante d'esprit, vous pouvez contourner le problème.
De commencer avec un nouveau comportement de l'extension comme ceci:
Alors vous avez besoin d'un moyen de remplacer le comportement par défaut. L'unité ne dispose pas d'une méthode pour supprimer une extension spécifique, de sorte que vous avez à tout supprimer et mettre les autres extensions de retour à nouveau:
Avis que
UnityClearBuildPlanStrategies
? RemoveAllExtensions efface toutes les conteneur des listes internes de politiques et de stratégies, sauf une, j'ai donc dû utiliser un autre poste pour éviter l'insertion de doublons quand j'ai restauré les extensions par défaut:Maintenant, vous pouvez utiliser en toute sécurité RegisterInstance sans crainte d'être au bord de la folie. Juste pour être sûr, voici quelques tests:
UnityContainer
instance EntLib utilise en interne, alors vous devriez être en mesure d'utiliser leInstallCoreExtensions
méthode. Vous devez vérifier que EntLib ne pas ajouter des extensions de son propre - si c'est le cas, vous devez les ajouter en aprèsInstallCoreExtensions
supprime tout.Fixe dans la dernière version de l'Unité (2.1.505.2). L'obtenir via NuGet.
La réponse à votre question est malheureusement pas. J'ai suivi ce projet avec l'équipe de développement d'ici à Microsoft modèles & les pratiques de groupe (j'étais le dev y mener jusqu'à récemment)et nous avons eu cela comme un bug à prendre en compte pour EntLib 5.0. Nous avons fait quelques recherches, et en vint à la conclusion que c'était causé par certains des interactions inattendues entre notre code et le débogueur. Nous ne considérons un correctif mais cela s'est avéré plus complexe que le code existant. Dans la fin ce que cela a priorité ci-dessous d'autres choses et la barre n'était pas pour 5.
Désolé je n'ai pas de meilleure réponse pour vous. Si c'est une consolation, je la trouve trop irritant.
- Je utiliser cette courte solution:
et de l'utiliser comme ceci:
le problème est que la classe de base de ContainerControlledLifetimeManager s'attend à un SynchronizedSetValue faire un moniteur.Enter() par l'intermédiaire de la base.GetValue, cependant la ContainerControlledLifetimeManager classe ne parvient pas à le faire (apparemment, les développeurs n'ont pas 'casser à l'exception activé?).
ce qui concerne,
Koen
Rory solution est une grande grâce. Résolu un problème qui m'ennuie tous les jours!
J'ai fait quelques modifications mineures à Rory de solution pour qu'elle traite quelles que soient les extensions sont enregistrés (dans mon cas, j'ai eu un WPF Prisme/Composite extension)..
container.AddExtension(new UnityClearBuildPlanStrategies());
Attention à une erreur dans la direction de Zubin Appoo réponse: il n'y a UnityClearBuildPlanStrategies manquant dans son code.
Le droit d'extrait de code est:
L'unité 2.1 - août 2012 mise à jour corrigera le bug
L'adressage d'un thread d'un problème de sécurité:
http://unity.codeplex.com/discussions/328841
Amélioration de l'expérience de débogage sur le Système.Le filetage.SynchronizationLockException:
https://entlib.uservoice.com/forums/89245-general/suggestions/2377307-fix-the-system-threading-synchronizationlockexcep
Amélioration de l'expérience de débogage grâce à de meilleurs messages d'erreur quand un type ne peut pas être chargé:
http://unity.codeplex.com/workitem/9223
Soutenir un scénario de l'exécution d'une Accumulation de() sur une instance d'une classe qui ne possède pas de constructeur public:
http://unity.codeplex.com/workitem/9460
À faire la mise à jour de l'expérience aussi simple que possible pour les utilisateurs et pour éviter la nécessité pour l'assemblée de liaison des redirections, nous avons choisi de n'augmente que l'assemblée de version de fichier, pas le .NET version de l'assembly.
Ce qui pourrait vous aider:
Le tour est joué.