Last active
March 25, 2025 01:58
-
-
Save patrickhuber/31e8f9f0ce3ea94d36b139d31bad4d54 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
public class Program | |
{ | |
public static void Main() | |
{ | |
ILogger logger = new ConsoleLogger(); | |
IServicePartitionResolver servicePartitionResolver = new ServicePartitionResolver(); | |
servicePartitionResolver = new ResilientServicePartitionResolver(servicePartitionResolver, 3); | |
servicePartitionResolver = new CachingServicePartitionResolver(servicePartitionResolver); | |
servicePartitionResolver = new LoggingServicePartitionResolver(servicePartitionResolver, logger); | |
logger.Log(servicePartitionResolver.ResolveServicePartition(new Uri("http://www.google.com"))); | |
} | |
} | |
public interface IServicePartitionResolver | |
{ | |
string ResolveServicePartition(Uri serviceURI); | |
} | |
public class ServicePartitionResolver : IServicePartitionResolver | |
{ | |
public string ResolveServicePartition(Uri serviceURI) | |
{ | |
return serviceURI.ToString(); | |
} | |
} | |
public class ResilientServicePartitionResolver : IServicePartitionResolver | |
{ | |
IServicePartitionResolver servicePartitionResolver; | |
int retryCount; | |
public ResilientServicePartitionResolver(IServicePartitionResolver servicePartitionResolver, int retryCount = 1) | |
{ | |
this.servicePartitionResolver = servicePartitionResolver; | |
this.retryCount = retryCount; | |
} | |
public string ResolveServicePartition(Uri serviceURI) | |
{ | |
int currentAttempt = 0; | |
while (true) | |
{ | |
try | |
{ | |
return this.servicePartitionResolver.ResolveServicePartition(serviceURI); | |
} | |
catch (Exception) | |
{ | |
if (currentAttempt <= this.retryCount) | |
{ | |
continue; | |
} | |
throw; | |
} | |
} | |
} | |
} | |
public interface ILogger | |
{ | |
void Log(string message); | |
void LogError(Exception ex); | |
} | |
public class ConsoleLogger : ILogger | |
{ | |
public void Log(string message) | |
{ | |
Console.WriteLine(message); | |
} | |
public void LogError(Exception ex) | |
{ | |
Console.Error.WriteLine(ex.Message); | |
} | |
} | |
public class LoggingServicePartitionResolver : IServicePartitionResolver | |
{ | |
IServicePartitionResolver servicePartitionResolver; | |
ILogger logger; | |
public LoggingServicePartitionResolver(IServicePartitionResolver servicePartitionResolver, ILogger logger) | |
{ | |
this.servicePartitionResolver = servicePartitionResolver; | |
this.logger = logger; | |
} | |
public string ResolveServicePartition(Uri serviceURI) | |
{ | |
this.logger.Log($"{nameof(IServicePartitionResolver)}.{nameof(ResolveServicePartition)}({nameof(serviceURI)}: {serviceURI})"); | |
try | |
{ | |
return this.servicePartitionResolver.ResolveServicePartition(serviceURI); | |
} | |
catch (Exception ex) | |
{ | |
this.logger.LogError(ex); | |
throw; | |
} | |
} | |
} | |
public class CachingServicePartitionResolver : IServicePartitionResolver | |
{ | |
IServicePartitionResolver servicePartitionResolver; | |
ConcurrentDictionary<Uri, string> cache; | |
public CachingServicePartitionResolver(IServicePartitionResolver servicePartitionResolver) | |
{ | |
this.servicePartitionResolver = servicePartitionResolver; | |
this.cache = new ConcurrentDictionary<Uri, string>(); | |
} | |
public string ResolveServicePartition(Uri serviceURI) | |
{ | |
return this.cache.GetOrAdd(serviceURI, (uri) => this.servicePartitionResolver.ResolveServicePartition(uri)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment