0

我正在尝试实现一个 InterceptAttribute,它应该拦截我添加属性的任何方法。我让它在 WebAPI 解决方案中工作,但是,我无法让它在 MVC 5 应用程序中工作。两个项目中的代码相同。以下代码是我创建的属性。

using Ninject;
using Ninject.Extensions.Interception;
using Ninject.Extensions.Interception.Attributes;
using Ninject.Extensions.Interception.Request;

namespace Questionnaire.Common.InterceptAttributes
{
    public class InterceptCacheAttribute : InterceptAttribute
    {
        public double TimeOut { get; set; }

        public override IInterceptor CreateInterceptor(IProxyRequest request)
        {
            var cacheInterceptor = request.Kernel.Get<CacheInterceptor>();
            cacheInterceptor.TimeOut = TimeOut;
            return cacheInterceptor;
        }
    }
}

CacheInterceptor 代码如下:

using System;
using System.Text;
using Ninject;
using Ninject.Extensions.Interception;
using Ninject.Extensions.Interception.Request;

namespace Questionnaire.Common.Interceptors
{
    public class CacheInterceptor : IInterceptor
    {
        [Inject]
        public ICaching Cache { get; set; }
        public double TimeOut { get; set; }

        public void Intercept(IInvocation invocation)
        {
            var minutes = Cache.TimeOutMinutes;
            if (Math.Abs(TimeOut - default(double)) > 0)
            {
                minutes = TimeOut;
            }
            invocation.ReturnValue = Cache.Get(GenerateCacheKey(invocation.Request), minutes, delegate
            {
                invocation.Proceed();
                return invocation.ReturnValue;
            });

        }

        private static string GenerateCacheKey(IProxyRequest request)
        {
            var sb = new StringBuilder(request.Method.Name).Append(".");
            foreach (var argument in request.Arguments)
            {
                if (argument == null)
                {
                    sb.Append("null");
                }
                else if (argument is string && argument.ToString().Length < 50)
                {
                    sb.Append((string)argument);
                }
                else
                {
                    sb.Append(argument.GetHashCode());
                }
                sb.Append(".");
            }
            sb.Remove(sb.Length - 1, 1);
            return sb.ToString();

        }
    }
}

最后,我将属性添加到以下方法中。

using System.Configuration;
using Questionnaire.Common.InterceptAttributes;

namespace Questionnaire.Common.Utility
{
    public class ConfigurationUtilities
    {
        [InterceptCache(TimeOut = 1440)]
        public virtual string GetEnvironmentConnectionString(string name)
        {
            var connectionStringSettings = ConfigurationManager.ConnectionStrings[name + "_" + HostEnvironment];
            return connectionStringSettings != null ? connectionStringSettings.ConnectionString : null;
        }
    }
}

代码执行永远不会进入 InterceptCacheAttribute 类。我已将调试点放在该类和 CacheInterceptor 类中,并且永远不会命中调试点。该属性所在的方法执行得很好,但是,我希望它被拦截,而这并没有发生。我在不同的项目中有相同的代码。该项目是一个运行良好的 WebAPI 项目。这些方法被拦截,一切都按应有的方式运行。有人可以向我解释为什么我不能让它在 MVC 5 应用程序中工作吗?我将不胜感激。

回答 BatteryBackupUnit 的问题:答案是我不能。以下是我的 NinjectWebCommon.cs 类。

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Mayo.Questionnaire.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(Mayo.Questionnaire.App_Start.NinjectWebCommon), "Stop")]

namespace Questionnaire.App_Start
{
    using System;
    using System.Web;
    using System.Web.Http;
    using System.Linq;
    using ApplicationExtensions;
    using Microsoft.Web.Infrastructure.DynamicModuleHelper;
    using Ninject;
    using Ninject.Web.Common;

    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
                GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
                RegisterServices(kernel);
                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        private static void RegisterServices(IKernel kernel)
        {
            foreach (var module in from assembly in AppDomain.CurrentDomain.GetAssemblies()
                     select assembly.GetNinjectModules()
                     into modules
                     from module in modules
                     where !kernel.GetModules().Any(m => m.Name.Equals(module.Name))
                     select module)
            {
                kernel.Load(module);
            }
        }        
    }
}

在 RegisterServices 方法中,应用程序中的每个程序集都被迭代,并且从 NinjectModule 继承的任何类都被加载。但是,我无法验证它是否正常工作,因为我无法调试它。我试过了,但是,课堂上的执行从未停止过。我知道该类正在被实例化并且模块正在被加载,因为我在那些正在工作的模块中有绑定,但是,我无法验证它。

4

0 回答 0