I've converted an old library to .NET Core and implemented a ChannelFactory caching solution. The services which it connects to require basic authorization added to each request's HTTP headers. The header is added to each request with a ClientMesageInspector. Because the ClientMessageInspector is immutable once the first channel is created the ChannelFactory cache stores each instance in a dictionary with a key based on the ChannelFactory endpoint, username and password combination. Also, due to the overhead of creating the ChannelFactory I do not dispose of them. My concern is the usernames and passwords are kept in memory within the dictionary keys and also within the ClientMesageInspector added to the ChannelFactory. Is there a better solution to this? I've already asked the question over on the dotnet/wcf GitHub page and wanted to open it up to a bigger audience.
Thanks in advance.
Bob.
I had some great help from the dotnet/wcf team via my question. After some discussion I ended up using AsyncLocal variables to store the username and password.
In the wrapper class we have the two AsyncLocal variables which are set via the constructor.
internal static AsyncLocal<string> Username = new AsyncLocal<string>();
internal static AsyncLocal<string> Password = new AsyncLocal<string>();
public WCFWrapper(string username, string password) : this()
{
Username.Value = username;
Password.Value = password;
}
In the IClientMessageInspector BeforeSendRequest method, we simply use the variables.
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] =
"Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(WCFWrapper.Username.Value + ":" + WCFWrapper.Password.Value));
request.Properties[HttpRequestMessageProperty.Name] = httpRequestProperty;
return null;
}