1 //-----------------------------------------------------------------------
2 // <copyright file="AssociationMemoryStore.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth
.OpenId
{
8 using System
.Collections
.Generic
;
11 /// Manages a set of associations in memory only (no database).
13 /// <typeparam name="TKey">The type of the key.</typeparam>
15 /// This class should be used for low-to-medium traffic relying party sites that can afford to lose associations
16 /// if the app pool was ever restarted. High traffic relying parties and providers should write their own
17 /// implementation of <see cref="IAssociationStore<TKey>"/> that works against their own database schema
18 /// to allow for persistance and recall of associations across servers in a web farm and server restarts.
20 internal class AssociationMemoryStore
<TKey
> : IAssociationStore
<TKey
> {
22 /// For Relying Parties, this maps OP Endpoints to a set of associations with that endpoint.
23 /// For Providers, this keeps smart and dumb associations in two distinct pools.
25 private Dictionary
<TKey
, Associations
> serverAssocsTable
= new Dictionary
<TKey
, Associations
>();
28 /// Stores a given association for later recall.
30 /// <param name="distinguishingFactor">The distinguishing factor, either an OP Endpoint or smart/dumb mode.</param>
31 /// <param name="association">The association to store.</param>
32 public void StoreAssociation(TKey distinguishingFactor
, Association association
) {
34 if (!this.serverAssocsTable
.ContainsKey(distinguishingFactor
)) {
35 this.serverAssocsTable
.Add(distinguishingFactor
, new Associations());
37 Associations server_assocs
= this.serverAssocsTable
[distinguishingFactor
];
39 server_assocs
.Set(association
);
44 /// Gets the best association (the one with the longest remaining life) for a given key.
46 /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
48 /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key.
50 public Association
GetAssociation(TKey distinguishingFactor
) {
52 return this.GetServerAssociations(distinguishingFactor
).Best
;
57 /// Gets the association for a given key and handle.
59 /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
60 /// <param name="handle">The handle of the specific association that must be recalled.</param>
62 /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key and handle.
64 public Association
GetAssociation(TKey distinguishingFactor
, string handle
) {
66 return this.GetServerAssociations(distinguishingFactor
).Get(handle
);
71 /// Removes a specified handle that may exist in the store.
73 /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
74 /// <param name="handle">The handle of the specific association that must be deleted.</param>
76 /// True if the association existed in this store previous to this call.
79 /// No exception should be thrown if the association does not exist in the store
82 public bool RemoveAssociation(TKey distinguishingFactor
, string handle
) {
84 return this.GetServerAssociations(distinguishingFactor
).Remove(handle
);
89 /// Clears all expired associations from the store.
91 public void ClearExpiredAssociations() {
93 foreach (Associations assocs
in this.serverAssocsTable
.Values
) {
94 assocs
.ClearExpired();
100 /// Gets the server associations for a given OP Endpoint or dumb/smart mode.
102 /// <param name="distinguishingFactor">The distinguishing factor, either an OP Endpoint (for relying parties) or smart/dumb (for providers).</param>
103 /// <returns>The collection of associations that fit the <paramref name="distinguishingFactor"/>.</returns>
104 internal Associations
GetServerAssociations(TKey distinguishingFactor
) {
106 if (!this.serverAssocsTable
.ContainsKey(distinguishingFactor
)) {
107 this.serverAssocsTable
.Add(distinguishingFactor
, new Associations());
110 return this.serverAssocsTable
[distinguishingFactor
];