Jetable singleton en C#
J'ai un singleton qui utilise le "static readonly T Instance = new T();" modèle. Cependant, j'ai couru dans un cas où T est jetable, et en fait doit être éliminée pour les tests unitaires. Comment puis-je modifier ce schéma à l'appui d'un revenu singleton?
L'interface, je voudrais, c'est quelque chose comme:
var x = Foo.Instance;
var y = Foo.Instance; //x == y
...
x.Release(); //this causes the next Foo.Instance to return a fresh object
//also, it assumes no further operations on x/y will be performed.
Note - le modèle doit être thread-safe, bien sûr.
Modifier - pour les fins de la production de code, c'est un vrai singleton. Le truc, c'est que, il bloque certains fichiers, et donc pour le nettoyage dans les tests unitaires, nous avons à mettre au rebut.
Je préfère également un modèle qui peut être réutilisé, si possible.
- Si vous pouvez faire de nouveaux T() qui signifie que vous devez avoir une contrainte générique de T avoir un public constructeur sans paramètre - dans ce cas, c'est pas un singleton pour commencer.
- J'ai juste écrit comme un modèle, il n'est pas vraiment droit générique maintenant à tous. Ce que j'ai est une classe qui appelle son constructeur privé et l'assigne au public static readonly champ.
Vous devez vous connecter pour publier un commentaire.
Marque
Release
commeinternal
et l'utilisation de laInternalsVisibleTo
attribut de les exposer uniquement à votre unité de test de l'assemblée. Vous pouvez soit le faire, ou si vous êtes méfier de quelqu'un dans votre propre assemblée vais l'appeler, vous pouvez le marquer commeprivate
et accéder à l'aide de la réflexion.L'utilisation d'un outil de finalisation dans votre singleton qui appelle la
Dispose
méthode sur l'instance du singleton.Dans le code de production, seul le déchargement d'un
AppDomain
entraînera l'élimination du singleton. Dans le code de test, vous pouvez lancer un appel àRelease
vous-même.À ce point, je ne pense pas que j'aimerais vraiment la considérer comme un singleton plus, pour être honnête.
En particulier, si un client utilise un singleton ils sont vraiment ne va pas attendre qu'ils ont à mettre au rebut, et ils serais surpris si quelqu'un d'autre l'a fait.
Quel est votre code de production va faire?
EDIT: Si vous avez vraiment, vraiment besoin de cela pour les tests unitaires et seulement pour les tests unitaires (qui semble discutable en termes de conception, pour être franc) puis vous pouvez toujours jouer avec le terrain à l'aide de la réflexion. Il serait plus agréable de savoir s'il devrait vraiment être un singleton ou si elle doit vraiment être jetables, les deux vont très rarement ensemble.
Singletons ne doit pas être Jetables. Période. Si quelqu'un appelle Éliminer prématurément, votre demande est vissé jusqu'à ce qu'il redémarre.
Si la classe implémente IDisposable (comme vous le laissez entendre il le fait), puis il suffit d'appeler x.Dispose()
Vous pouvez utiliser un imbriquée paresseux singleton (Voir ici), avec quelques modifications simples:
N'oubliez pas de jeter ObjectDisposedException dans toutes les méthodes/propriétés de l'objet s'il a été disposé.
Vous devez également fournir un finaliseur méthode de l'objet, en cas d'Aliéner n'est pas appelée. Voir comment implémenter correctement IDisposable ici.
Pour les tests unitaires vous pouvez utiliser un "manuel" exemple (mais il aurait besoin d'un moyen pour instancier l'objet).
Dans votre cas, vous devriez probablement mieux d'utiliser le modèle de fabrique (abstrait/méthode - quel est le meilleur pour votre cas), combiné avec un singleton.
Si vous voulez tester si le singleton a disposé correctement des objets utilisés (dans l'unité de test), puis utiliser la méthode de factorisation, sinon utilisez le pattern singleton.
Par ailleurs, si vous n'avez pas accès à l'singleton code source ou vous n'êtes pas autorisé à modifier, vous permettrait de mieux l'envelopper d'un autre singleton, et de fournir toute la logique de la nouvelle (plus comme un proxy). Il sonne comme overkill, mais il pourrait être une solution viable.
Aussi, afin d'être en mesure de contrôler l'accès, fournir une usine, et de laisser les clients à obtenir le nouvel objet que si l'objet n'a pas été éliminé.
Une autre option pour faire un jetable Singleton est d'utiliser des Châteaux de la [Singleton] attribut pour votre classe, puis Château-cadre prend soin de disposer de tous les jetables objets Singleton