使用温莎城堡与拦截器和asp.net [英] Using castle windsor with interceptors and asp.net
问题描述
我试图用面向方面编程使用温莎城堡纯asp.net添加日志记录,即不MVC
I'm trying to add logging with aspect orientated programming using castle windsor in plain asp.net, i.e. not MVC
我添加了实现IInterceptor接口,并从属性继承属性的类。
I've added a class that implements the IInterceptor interface and an attribute that inherits from Attribute.
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我添加以下内容:
Now in the global.asax.cs I've added the following:
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();
}
和我创建了一个安装程序类:
and I've created an installer class:
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);
}
}
我现在想要添加的属性隐藏类和一些arbitary虚方法有些arbitary页的code,如
I now want to add the attribute to some arbitary page's code behind class and some arbitary virtual method, as in
[Log(Level.Info)]
protected string Login(string username, string password)
{
DoSomething();
}
这显然是行不通的。我需要改变我的实例页面(其页面的code-隐藏类)使用容器的方式?或者是我注册的拦截器的方式吗?我希望能够使用前进,而不是任何类的拦截器必须告诉每一个类,我在我的应用程序容器中。
This obviously doesn't work. Do I need to change the way I'm instantiating the page (its a page's code-behind class) to use a container? Or is it the way I'm registering the interceptors? I want to be able to use the interceptors on any class going forward and not have to tell the container about each and every class that I have in my application.
推荐答案
简短的回答:这是不可能的。
Short answer: it's not possible.
龙答:由于道路ASP.NET Web窗体的作品,它不会让任何人的页面实例干涉。有人声称,使用自定义PageHandlerFactory让你做的IoC,但这只让你设置属性的之后的网页已经被实例化,这是根本不够的代理。
Long answer: due to the way ASP.NET Web Forms works, it doesn't let anyone interfere with the page instantiation. Some claim that using a custom PageHandlerFactory lets you do IoC, but this only lets you set properties after the page has been instantiated, which is simply not enough for proxying.
所以运行时库代理,如DynamicProxy或李林甫不能做这个事情。但是你可能能够使用编译时织工方面,如 PostSharp 。
So runtime proxy libraries such as DynamicProxy or LinFu can't do anything about this. But you may be able to use compile-time aspect weavers, such as PostSharp.
另外,让您的code-落后于轻薄越好,推迟实际的逻辑温莎管理组件。
Alternatively, make your code-behind as slim as possible, deferring actual logic to Windsor-managed components.
这篇关于使用温莎城堡与拦截器和asp.net的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!