как получить доступ к объекту, который я перехватываю? - PullRequest
1 голос
/ 18 января 2011

Я использую Castle Core для создания настраиваемого атрибута и перехватчика для внедрения проверок безопасности в наш код с использованием атрибутов.например, [Security ("Role1")]

В реализации перехватчика:

public class SecurityInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        object o;

        MethodInfo mi = invocation.Method;
        SecurityAttribute[] atts = (SecurityAttribute[])mi.GetCustomAttributes(typeof(SecurityAttribute), true);

        // if method not marked with Security attribute, then pass on call
        if (atts.Length == 0)
        {
            invocation.Proceed();
        }
        else
        {
            //for now assume that there is only one security attribute on the method
            //do some security test 
            {
                invocation.Proceed();
            }
        }

    }

В приведенном выше разделе "сделать тест безопасности" мне нужен доступ к HttpContext.Sessionобъект для извлечения некоторых сохраненных объектов для проведения теста безопасности.

Предположим, что метод, к которому относится этот атрибут, является страницей asp.net с выделенным кодом, то есть экземпляром класса Page)t просто используйте this.Context в атрибуте, подобном this [Security ("Role1", this.Context)], поскольку атрибуты этого не допускают.

Итак, как мне получить доступ к httpContext внутри метода Intercept?

Или есть ли лучший способ сделать это аспектно-подобным способом?

Ответы [ 2 ]

4 голосов
/ 19 января 2011

Свойство InvocationTarget экземпляра IInvocation содержит целевой объект. Так что в вашем случае, если вы уверены, что перехват происходит на Page объекте, вы должны быть в состоянии сделать это:

var page = (Page)invocation.InvocationTarget;

Если это не всегда так, вы должны получить доступ к HTTP-контексту другим способом.

Это верно, как указывает Бен, что HttpContext.Current дает вам доступ к текущему HttpContext из любого места, но доступ к этому статическому свойству просто неприличен. Однако есть и лучший способ - зарегистрировать фабричный метод, который позволяет вводить состояние сеанса:

container.Register(
    Component.For<ISessionState>()
        .UsingFactoryMethod(k => new SessionWrapper(HttpContext.Current.Session)
        .Lifestyle.PerWebRequest));

при условии, что вы создали интерфейс ISessionState и соответствующую оболочку с API, который вы хотите использовать при взаимодействии с объектом ASP.NET HttpSessionState.

Теперь, поскольку перехватчик извлекается из контейнера, как и все остальное, он может зависеть от ISessionState:

public class SecurityInterceptor : IInterceptor
{
    public SecurityInterceptor(ISessionState sessionState)
    {
        //...
    }
}

, что делает ваш перехватчик красивым и тестируемым.

Возможно, есть много других способов сделать это, а также, возможно, и лучшие. Это просто идея о том, как вы можете продолжить свой проект:)

1 голос
/ 18 января 2011

Вы можете использовать HttpContext.Current.Session из любого места, если код вызывается из процесса ASP.net.

...