HttpModuleにパラメータを渡す方法

HttpModule好きなんですが、JavaServlet Filterのように設定でパラメータを渡せないのが残念なところです。そこで、Web.configにパラメータを設定をすればHttpModuleのプロパティに自動で設定される仕組みを考えてみました。


例えば、Web.configに以下の感じで記述して、MyModuleのTimeoutプロパティに10を設定したいのです。


<configSections>
<sectionGroup name="my.system.webServer">
<section name="modules" type="WebApplication.ModulesSection, WebApplication" />
</sectionGroup>
</configSections>

<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="MyModule" type="WebApplication.MyModule, WebApplication" />
</modules>
</system.webServer>

<my.system.webServer>
<modules>
<moduleSettings name="MyModule">
<add key="Timeout" value="10" />
</moduleSettings>
</modules>
</my.system.webServer>


例外ハンドリングやキャッシュはまったく考えていませんが、次のようなコードを書けば実現できそうです。


using System;
using System.Configuration;
using System.Web;
using System.Web.Configuration;

namespace WebApplication
{
public class ModulesSection : ConfigurationSection
{
[ConfigurationProperty("", IsDefaultCollection = true)]
[ConfigurationCollection(typeof(ModuleSettingCollection), AddItemName = "moduleSettings")]
public ModuleSettingCollection ModuleSettings
{
get
{
return (ModuleSettingCollection) base[""];
}
}
}

public class ModuleSettingCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new KeyValueConfigurationCollection();
}

protected override object GetElementKey(ConfigurationElement element)
{
return ((KeyValueConfigurationCollection) element).Name;
}

public KeyValueConfigurationCollection Get(string name)
{
return (KeyValueConfigurationCollection) BaseGet(name);
}
}

public class KeyValueConfigurationCollection : ConfigurationElementCollection
{
[ConfigurationProperty("name", DefaultValue = "", IsKey = true, IsRequired = true)]
public string Name
{
get
{
return (string) this["name"];
}
set
{
this["name"] = value;
}
}

protected override ConfigurationElement CreateNewElement()
{
return new KeyValueConfigurationElement();
}

protected override object GetElementKey(ConfigurationElement element)
{
return ((KeyValueConfigurationElement) element).Key;
}
}

public class KeyValueConfigurationElement : ConfigurationElement
{
[ConfigurationProperty("key", DefaultValue = "", IsKey = true, IsRequired = true)]
public string Key
{
get
{
return (string) this["key"];
}
set
{
this["key"] = value;
}
}

[ConfigurationProperty("value", DefaultValue = "")]
public string Value
{
get
{
return (string) this["value"];
}
set
{
this["value"] = value;
}
}
}

public abstract class ParamAwareModuleBase : IHttpModule
{
protected ParamAwareModuleBase()
{
}

public virtual void Init(HttpApplication context)
{
var moduleName = GetModuleName(context);
var modulesSection = (ModulesSection) WebConfigurationManager.GetSection("my.system.webServer/modules");
var keyValueCollection = modulesSection.ModuleSettings.Get(moduleName);
foreach (KeyValueConfigurationElement element in keyValueCollection)
{
var property = GetType().GetProperty(element.Key);
if (property.CanWrite)
{
var value = Convert(property.PropertyType, element.Value);
property.SetValue(this, value, null);
}
}
}

public virtual void Dispose()
{
}

protected virtual string GetModuleName(HttpApplication context)
{
var moduels = context.Modules;
var count = moduels.Count;
for (var i = 0; i < count; i++)
{
var module = moduels.Get(i);
if (module == this)
{
return moduels.GetKey(i);
}
}
throw new InvalidOperationException("module not found.");
}

protected virtual object Convert(Type type, string value)
{
if (type == typeof(int))
{
return System.Convert.ToInt32(value);
}
return value;
}
}

public class MyModule : ParamAwareModuleBase
{
public int Timeout { get; private set; }

public override void Init(HttpApplication context)
{
base.Init(context);
//...
}
}
}

こういう機能って標準ではないですよね?