Monday, March 2, 2020

Read WCF Service Web.config Sections and Values

Get the Web.Config contents as a Configuration object.
private static Configuration GetWebConfig()
{
    var vdm = new VirtualDirectoryMapping(System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath, true);
    var wcfm = new WebConfigurationFileMap();
    wcfm.VirtualDirectories.Add("/", vdm);

    var webConfig = WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");

    return webConfig;
}
Get a value from the appSettings section.
public static string GetConfigurationValue(string keyName)
{
    string value = null;

    var webConfig = GetWebConfig();

    if (webConfig.AppSettings.Settings.Count > 0)
    {
        var setting = webConfig.AppSettings.Settings[keyName];
        if (setting != null)
        {
            value = setting.Value;
        }
    }

    return value;
}
Get a specific binding.
public static Binding ResolveBinding(string name)
{
    var section = GetBindingsSection();
    var nameLower = name.ToLower();

    foreach (var bindingCollection in section.BindingCollections.Where(collection => collection.ConfiguredBindings.Any()))
    {
        var bindingElement = bindingCollection.ConfiguredBindings.FirstOrDefault(element => element.Name.ToLower() == nameLower);
        if (bindingElement == null)
        {
            continue;
        }

        var binding = (Binding)Activator.CreateInstance(bindingCollection.BindingType);
        binding.Name = bindingElement.Name;
        bindingElement.ApplyConfiguration(binding);

        return binding;
    }

    var message = $"Binding with name '{name}' could not be found in the service web.config.";
    throw new FaultException(new FaultReason(message));
}
Get a specific endpoint.
public static ChannelEndpointElement ResolveClientEndpoint(string name)
{
    var section = GetClientSection();
    var nameLower = name.ToLower();

    var endpoint = section.Endpoints.OfType()
        .FirstOrDefault(e => e.Name.ToLower() == nameLower);

    if (endpoint != null)
    {
        return endpoint;
    }

    var message = $"Client endpoint with name '{name}' could not be found in the service web.config.";
    throw new FaultException(new FaultReason(message));
}
Get the Binding section.
public static BindingsSection GetBindingsSection()
{
    var webConfig = GetWebConfig();
    var bindingSection = ServiceModelSectionGroup.GetSectionGroup(webConfig)?.Bindings;

    if (bindingSection != null)
    {
        return bindingSection;
    }

    const string message = "The service web.config is missing the bindings section.";
    throw new FaultException(new FaultReason(message));
}
Get the Client section.
public static ClientSection GetClientSection()
{
    var webConfig = GetWebConfig();
    var clientSection = ServiceModelSectionGroup.GetSectionGroup(webConfig)?.Client;

    if (clientSection != null)
    {
        return clientSection;
    }

    const string message = "The service web.config is missing the client section.";
    throw new FaultException(new FaultReason(message));
}

Performance: Linking a List of Child Objects To a List of Parent Objects

Many a time I've had to build a relationship where a parent object has a list of child objects linked to it, where the parent itself als...