Is there a way to access a NameValueCollection (like Request.Form or ConfigurationManager.AppSettings) as a dynamic object?
I'd like to be able to do something like this:
var settings = ConfigurationManager.AppSettings.AsDynamic();
var name = settings.Name; // ConfigurationManger.AppSettings["Name"]
// but also
settings.Name = "Jones"; // modify the original collection
// and
var form = Request.Form.AsDynamic();
var email = form.Email; // Request.Form["Email"]
(this question is based on Convert a NameValueCollection to a dynamic object )
You could write an adapter that wraps your NameValueCollection and that inherits from DynamicObject. You could then create an extension method that instantiates the adapter. To finish it off, you could make your wrapper class implicitly castable to you original NameValueCollection, so you could use the wrapped collection everywhere you would be able to use the original collection:
public static class Utility
{
public static dynamic AsDynamic(this NameValueCollection collection)
{
return (NameValueCollectionDynamicAdapter)collection;
}
private class NameValueCollectionDynamicAdapter : DynamicObject
{
private NameValueCollection collection;
public NameValueCollectionDynamicAdapter(NameValueCollection collection)
{
this.collection = collection ?? throw new NullReferenceException(nameof(collection));
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = collection[binder.Name];
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
collection[binder.Name] = value?.ToString();
return true;
}
public static implicit operator NameValueCollection(NameValueCollectionDynamicAdapter target)
{
return target.collection;
}
public static explicit operator NameValueCollectionDynamicAdapter(NameValueCollection collection)
{
return new NameValueCollectionDynamicAdapter(collection);
}
}
}