IronPython for ASP.Net 的屬性注入器機制可以使得一些代碼的語法變得簡單(詳細了解參考我的這一篇),但是默認的支持似乎現在還很不完備。
我反編譯了 Microsoft.Web.IronPython.dll,在其中增加了對 RepeaterItem 和 Session (HttpSessionState) 的屬性注入支持。
對 RepeaterItem 的支持很簡單,因為本身已經有了 ControlAttributesInjector. 所以只要在 DynamicLanguageHttpModule.cs 的靜態構造器中加一行代碼即可:
// repeater item
Ops.RegisterAttributesInjectorForType(typeof(RepeaterItem), new ControlAttributesInjector(), false);
而 Session 則不那麼幸運,這個類實現了 ICollection,但是確沒有實現 IDictionary 接口。所以就無法利用 DictionaryAttributesInjector. 沒辦法,我自己給加了個 SessionAttributesInjector 類。代碼如下:
using IronPython.Runtime;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Web.SessionState;
using System.Diagnostics;
namespace Microsoft.Web.IronPython.AttributesInjectors {
// added by Neil Chen.
internal class SessionAttributesInjector: IAttributesInjector {
List IAttributesInjector.GetAttrNames(object obj) {
HttpSessionState session = obj as HttpSessionState;
List list = new List();
foreach (string key in session.Keys) {
list.Add(key);
}
return list;
}
bool IAttributesInjector.TryGetAttr(object obj, SymbolId nameSymbol, out object value) {
HttpSessionState session = obj as HttpSessionState;
value = session[nameSymbol.GetString()];
return true;
}
}
}
附上我修改過的 Microsoft.Web.IronPython.dll
需要說明的是,屬性注入器只對 get 操作有用,比如
name = Session.Name 是可以的,
但是設置則不行:
Session.Name = 'some name' 會報錯。
還是需要用這個語法:
Session["Name"] = 'some name'