属性を追加するメソッドをインターセプトする 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 から継承するすべてのクラスが読み込まれます。ただし、デバッグできないため、機能していることを確認できません。試してみましたが、クラス内で実行が停止することはありません。クラスがインスタンス化され、モジュールがロードされていることはわかっています。これらのモジュールには動作しているバインディングがあるためですが、それを確認することはできません。