2011-01-24 156 views
3

我試圖以純asp.net使用溫莎城堡面向方面編程,即添加日誌記錄不MVC使用溫莎城堡與攔截器和asp.net

我添加了實現IInterceptor接口的類以及從屬性繼承的屬性。

public class LogAttribute : Attribute 
{ 
    public Level LogLevel { get; set; } 

    public LogAttribute(Level level) 
    { 
     LogLevel = level; 
    } 
} 

public class LoggingInterceptor : IInterceptor 
{ 

    public void Intercept(IInvocation invocation) 
    { 

     MethodInfo mi = invocation.Method; 
     LogAttribute[] atts = (LogAttribute[])mi.GetCustomAttributes(typeof(LogAttribute), true); 
     // if method not marked with InternalUseRestricted attribute, then pass on call 
     if (atts.Length == 0) 
     { 
      invocation.Proceed(); 
     } 
     else 
     { 
      ISeiLogger log = LoggerFactory.GetLogger(mi.DeclaringType.ToString()); 
      //assume only one logging attribute 
      //log on entry 
      log.LogEnter(atts[0].LogLevel); 
      //allow code to continue 
      invocation.Proceed(); 
      //log on exit 
      log.LogExit(atts[0].LogLevel); 
     } 
    } 
} 

現在在的global.asax.cs我已經添加了以下內容:

public partial class Global : System.Web.HttpApplication, IoCProvider 
{ 

    private void InitializeIoC() 
    { 
     container = new WindsorContainer(); 
     container.Install(new Sei.Aspect.AspectInstaller()); 
    } 

    public IWindsorContainer Container 
    { 
     get { return container; } 
    } 

    private static Sei.Logging.ISeiLogger log; 
    private IWindsorContainer container; 

    public override void Init() 
    { 
     base.Init(); 

     InitializeIoC(); 
    } 

和我創建了一個安裝程序類:

public class AspectInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     //container.Register(AllTypes.FromAssembly(Assembly.GetExecutingAssembly()).BasedOn<IInterceptor>().Configure(component => component.LifeStyle.PerWebRequest)); 
     container.Register(Component.For<IInterceptor>().ImplementedBy<LoggingInterceptor>().LifeStyle.PerWebRequest); 
     container.Register(Component.For<IInterceptor>().ImplementedBy<InternalUseRestrictedInterceptor>().LifeStyle.PerWebRequest); 
     container.Register(Component.For<IInterceptor>().ImplementedBy<CachingInterceptor>().LifeStyle.PerWebRequest); 
    } 
} 

我現在想添加該屬性以一些任意的頁面代碼爲背後的類和一些任意的虛擬方法,如

[Log(Level.Info)] 
    protected string Login(string username, string password) 
    { 
     DoSomething(); 
    } 

這顯然不起作用。我是否需要改變實例化頁面(其頁面的代碼隱藏類)以使用容器的方式?或者是我註冊攔截器的方式?我希望能夠在任何課堂上使用攔截器,而不必告訴容器我的應用程序中有每個課程。

回答

1

簡答:這是不可能的。

長答案:由於ASP.NET Web窗體的工作方式,它不會讓任何人干擾頁面實例化。有人聲稱使用自定義PageHandlerFactory可以讓你做IoC,但是這隻允許你在頁面被實例化後設置屬性,這對於代理來說是不夠的。

因此,運行時代理庫(如DynamicProxy或LinFu)無法對此做任何事情。但是你也許可以使用編譯時方面編織器,例如PostSharp

或者,儘可能使代碼隱藏,將實際邏輯推遲到Windsor管理的組件。