10

I have relation between two classes Credentials<=>UserData. And I would like to use MemoryCache to filter my incoming request.

My key = Credential and value = UserData.

(Data)MemoryCache.Default.AddOrGetExisting(GetKey(credential), // must be a string
                                           userData,
                                           DateTime.Now.AddMinutes(5));

How can I implement public string GetKey(Credentials credential) for incoming request?

Credentials its a DataContract that contains other DataContracts like GoogleCredentials, FacebookCredentials. And they contains their own strings like user_name and password.

Now the cache items are added with keys credential.ToString() and it is important for this method to return the same value for Credentials objects having the same credential values, and distinct values for Credentials instances with different credential values.

Inside Credential class I have the following method

public override int GetHashCode()
{
    int hashCode = 0;

    if (GoogleCredentials!= null)
    {
        hashCode ^= GoogleCredentials.GetHashCode();
    }

    if (FacebookCredentials!= null)
    {
        hashCode ^= FacebookCredentials.GetHashCode();
    }

    return hashCode;
}
  • What type is your GoogleCredentials and etc? Can you add source code of your Credentials class and other used classes? – Vadim Martynov Dec 25 '15 at 17:06
  • Its other `DataContract` that have their own strings like `UserName` and `Password` –  Dec 25 '15 at 17:10
  • Having one single container class for multiple credentials makes it harder then it should be I think. Why not have separate collections so you can do key = username + password (or the hash of that)? – Wouter de Kort Dec 27 '15 at 10:30

1 Answers1

3

It's a question about data and object uniqueness. In .NET there is a mechanism to compare two objects. It uses Equals and GetHashCode methods. There is another method with EqualityComparer which based on same mechanisms.

GetHashCode return a unique integer code for your object. You can override this method for your credential class or create external method which will work similarly and then call ToString() for unique code. There are many guides how to implement GetHashCode in a right way. Actual implementation will depends on your object structure.

Community
  • 1
  • 1
Vadim Martynov
  • 8,602
  • 5
  • 31
  • 43
  • Update the question. How can I use my GetHashCode method to create a key for the AddOrGetExisting ? –  Dec 27 '15 at 13:10
  • As I can understand you implement GetHashCode for all 3 classes: Credentials, FacebookCredentials and GoogleCredentials. In my opinion there is no reasons to override this function explicitly because it can make a (very little and minor) performance issue if your objects compare in other scenarios. In my opinion it is better to implement the same function in the external code (for example, in method GetKey) when possible. – Vadim Martynov Dec 27 '15 at 18:39
  • No, Credentials contains FacebookCredentials and GoogleCredentials as property –  Dec 27 '15 at 19:56
  • I understand it. But if you call GetHashCode for GoogleCredentials and don't override this method in GoogleCredentials's class the code will compute based on reference to an instance instead of instance data. I still believe that it is necessary to implement GetСode as external method to Credentials class and call GetHashCode inside this implementation only for simple (value) types, as recommended by the manuals above. – Vadim Martynov Dec 28 '15 at 07:29
  • It's VITAL to know that default GetHashCode is not unique. Two different objects may generate the same hash code. This may lead to severe consequences if you would like to for example cache objects and reuse it. Refer to remarks in this page https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode?view=net-6.0#system-string-gethashcode – Adel Tabareh Jun 17 '22 at 13:29