MVC と WebAPI の両方を使用する MVC4 サイトがあります。クラスを変更して、データのキャッシュに役立つクロスカット AOP クラスを作成しようとするまで、すべてがうまくいっていました。現在、InterceptAttribute を持たないメソッドを呼び出すと、Ninject がパラメーターを挿入しなかったためにクラッシュし、失敗することがわかりました。
私の BLL クラスは次のようになります。
public class FooBLL
{
#region Private Variables
private readonly IDAL _context;
#endregion
#region Constructor
public Foo(IDAL context)
{
_context = context;
}
#endregion
#region Public Methods
public List<Bar> GetAllBars()
{
return _context.GetAllBars();
}
public List<Bar> GetTwoBars()
{
return _context.GetTwoBars();
}
#endregion
}
私の WebApi コントローラーは次のようになります。
public class FooController : ApiController
{
#region Private Variables
private readonly FooBLL _fooBll;
#endregion
#region Constructor
public FooController(FooBLL fooBll)
{
_fooBll = fooBll;
}
#endregion
#region Public Methods
#region Estimate Types
#region Get
public List<Bar> GetAllBars()
{
return _fooBll.GetAllBars();
}
public List<Bar> GetTwoBars()
{
return _fooBll.GetTwoBars();
}
#endregion
#endregion
#endregion
}
私の Web サイトでは、コントローラーを解決するために次の Ninject クラスを作成しました。
public class NinjectRegistrations : NinjectModule
{
public override void Load()
{
Kernel.Bind<IDAL>().To<DAL>().InSingletonScope();
}
}
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
private readonly IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(this.kernel.BeginBlock());
}
}
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void Dispose()
{
var disposable = this.resolver as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
this.resolver = null;
}
public object GetService(Type serviceType)
{
if (this.resolver == null)
{
throw new ObjectDisposedException("this", "This scope has already been disposed");
}
return this.resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (this.resolver == null)
{
throw new ObjectDisposedException("this", "This scope has already been disposed");
}
return this.resolver.GetAll(serviceType);
}
}
Global.asax で、このリゾルバーを登録します。
NinjectHelper.Kernel = new StandardKernel(modules);
var ninjectResolver = new NinjectDependencyResolver(NinjectHelper.Kernel);
DependencyResolver.SetResolver(ninjectResolver); // MVC
GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; // Web API
//Register Filter Injector
GlobalConfiguration.Configuration.Services.Add(typeof(System.Web.Http.Filters.IFilterProvider), new NinjectWebApiFilterProvider(NinjectHelper.Kernel));
Ninject.Extensions.Interception.Attributes.InterceptAttribute を使用して属性 Cache を追加するまでは問題ありませんでした。
クラスは次のようになります (パラメーターなしのコンストラクターを追加し、メソッドの 1 つを仮想としてマークしたことに注意してください。これらは両方とも、傍受が機能するために必要です)。
public class FooBLL
{
#region Private Variables
private readonly IDAL _context;
#endregion
#region Constructor
public Foo(IDAL context)
{
_context = context;
}
public Foo()
{
}
#endregion
#region Public Methods
public List<Bar> GetAllBars()
{
return _context.GetAllBars();
}
[Cache(DefaultTimeoutMinutes = 20)]
public virtual List<Bar> GetTwoBars()
{
return _context.GetTwoBars();
}
#endregion
}
WebAPI コントローラーで GetToBars (Intercept 属性を持つメソッド) を呼び出すと、すべて正常に動作します。
ただし、GetAllBars (Intercept 属性を持たないメソッド) を呼び出すと、_context が null であるという例外で失敗します。
どんな助けでも大歓迎です。
ベン