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