Ninject拦截不适用于MVC 5

时间:2014-11-25 14:48:12

标签: ninject ninject.web.mvc ninject-extensions asp.net-mvc-5.2 ninject-interception

我正在尝试实现一个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继承的所有类。但是,我无法验证它是否正常工作,因为我无法调试它。我试过了,但是,在课堂上永远不会停止执行。我知道该类正在实例化,并且正在加载模块,因为我在那些工作的模块中有绑定,但是,我无法验证它。

0 个答案:

没有答案