J'écris une application qui a quelques caches d'objet. La façon dont il a besoin de fonctionner est quand un objet est extrait du cache: p> foo doit être une copie locale de l'objet d'origine, pas une référence. Quelle est la meilleure façon de mettre en œuvre cela? La seule façon dont j'ai à l'esprit jusqu'à présent, c'est d'utiliser un binaire pour créer une copie, mais je me sens comme si je manque d'une meilleure façon. P> Le support pour le cache La mise en œuvre est arbitraire, telle qu'elle est basée sur le fournisseur. J'ai besoin de prendre en charge un nombre quelconque de caches, du cache HTTPRuntime à quelque chose comme la vitesse. La mise au point ici est sur la couche entre le support de cache et le code de consommateur - cette couche doit s'assurer que la copie de l'objet est renvoyée. Certains caches feront déjà cela, mais certains ne le font pas (le cache HTTpruntime en étant un). P> h3> Détails h3>
3 Réponses :
Désolé, je dois souscrire cela. Pourquoi ne pas rechercher les objets dans un dictionnaire, puis créer une copie profonde de l'objet (par exemple, grossièrement: p> Si vous allez la route de réflexion, Marc Gravell a une belle Code de clonage facilement modifié pour créer une copie profonde. P> P> ideeepCopyable code>) ou utilisez la réflexion pour faire le travail?
Merci. Je ne suis pas tout à fait suivir - pouvez-vous élaborer?
C'est une bonne réponse compte tenu des informations limitées dans ma question. Cependant, je ne peux pas raisonnablement rendre l'objet responsable de la copie elle-même, et je ne peux pas utiliser un dictionnaire, car les fournisseurs de cache doivent être beaucoup plus robustes et avoir la possibilité d'utiliser un autre support de stockage (tel que le cache HTTPRuntime).
@Rex m: Pour le clonage, pouvez-vous utiliser la route de réflexion alors? Pour la mise en cache des objets, jetez un coup d'œil à la vitesse ( MSDN.MicRosoft.com/fr -us / données / cc655792.aspx ).
@Rex m: Si je comprends les détails supplémentaires que vous venez d'ajouter à votre question, vous souhaitez écrire un adaptateur sur des solutions de mise en cache existantes telles que l'adaptateur fournira une copie d'un objet stocké dans le cache des consommateurs? Je dois toujours sous-estimer cela, mais je ne vois pas comment la solution n'est pas un objet de recherche dans le cache, return Copie de l'objet créé à l'aide de la réflexion.
@Jason Vous ne sous-estimez certainement pas. Vous avez décrit ce que je suis après - si la réflexion est la bonne façon d'y aller, s'il vous plaît dites-le. Et si oui, quels sont les avantages de la réflexion sur la sérialisation binaire?
Rex - Nous avons mis en place quelque chose de très similaire dans un gros produit Web d'entreprise et nous avons fini par créer explicitement une interface ideepclyeable que nombre de nos objets mis en œuvre. La chose intéressante est que nous l'avons soutenu avec BinarySérialiseur, simplement parce que c'est un moyen conviennent et pratiquement infaillible de faire une copie profonde d'un objet sans que tous les tracas de la réflexion ou de forcer les développeurs à écrire et à tester des méthodes de clone. P>
Cela fonctionne comme un charme. Notre équipe s'est arrêtée à la charte à plusieurs reprises et nous n'avons pas encore une meilleure option. P>
Voici une simple fonction qui utilisera la réflexion sur une copie et un objet profond, quel que soit leur type. Je l'ai critiquée, en partie d'une routine de copie beaucoup plus complexe, j'ai utilisée dans les anciennes journées de services Web pour copier entre des types de données presque identiques (TM). Cela pourrait ne pas fonctionner exactement, cela vous donne l'idée générale. C'est très simpliste et lors de l'utilisation de la réflexion brute, il existe de nombreux cas de frontières ... personnellement, j'utiliserais les routines de sérialisation, car elles gèrent automatiquement tous les cas de frontières. Par défaut, au moins dans .NET 2.0, le système crée de manière dynamique l'assemblage de sérialisation. Vous pouvez accélérer la sérialisation en mettant en cache les sérialiseurs. Cet exemple de code de mon application met en cache les XMLSerializers. P> protected static XmlSerializer SerializerGet(System.Type type)
{
XmlSerializer output = null;
lock(typeof(SerializeAssist))
{
if(serializerList.ContainsKey(type))
{
output = serializerList[type];
}
else
{
if(type == typeof(object) || type == typeof(object[]) || type == typeof(ArrayList))
{
output = new XmlSerializer(type, objArrayTypes);
}
else
{
output = new XmlSerializer(type);
}
serializerList.Add(type, output);
}
}
return output;
}
Merci William. J'ai fait quelque chose de très similaire à votre sérialiseur XML - FYI, le vôtre n'a pas l'air de fil-coffre-fort.
Hahahah j'ai enlevé le code de sécurité de verrouillage et de fil pour le rendre plus clair. :-)
Ah :) Je recommanderais de l'ajouter de retour ... Nous ne voulons pas de pauvres dev obstérés à cette page par an et en laissant tomber cela dans son application de production!
Une fois de temps en temps, il est bon de voir des experts poser des questions;) BTW, quelle profondeur votre objet peut être? Fait référence à d'autres références d'objet, etc.?
@shahkalpeh Score High! = Expert, mais acclamations. Les caches devraient idéalement pouvoir stocker n'importe quel objet dans la raison. Je peux probablement ajouter l'exigence selon laquelle d'autres objets sont chargés de paresseux.
Rex, pourriez-vous décrire votre scénario un peu plus? Avez-vous besoin de chaque appel pour vous gérer une nouvelle copie de ce même objet dans un scénario client? Votre cache InproC ou hors Proc? Est-ce une application de serveur (je suppose-je oui)? Avez-vous des clients d'état connectés à cette application? Avez-vous une couche de mise en cache sur les clients aussi?
@Runtime nous concentrons simplement sur le serveur pour l'instant. Le cache peut être dans la procédure ou hors des proc, car les détails de mise en œuvre du cache sont laissés au fournisseur. Ce mécanisme devrait essentiellement être apatride. Lorsque j'obtiens une copie d'un objet hors du cache, je peux créer une session locale et la joindre si nécessaire.
La raison pour laquelle j'ai posé ces questions était de mieux comprendre vos besoins, car je ne suis pas sûr de savoir pourquoi auriez-vous besoin d'un tel schéma d'accès. Je veux dire, oui, vous devriez copier sur l'écriture à des fins de synchronisation, mais pourquoi également en lecture? Ce n'est pas comme des morceaux de données mis en cache seraient mis à jour sur place en interne.
@Runtime Parce que le fil d'appel peut effectuer un nombre quelconque de choses arbitraires à sa copie de l'objet, y compris les propriétés de réglage et les valeurs changeantes, que je ne souhaite pas être reflétée dans le cache ou sur la même entité dans d'autres threads. L'engagement de modifications et de nouveaux objets à la cache passe par un flux de travail entièrement différent.