1

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 であるという例外で失敗します。

どんな助けでも大歓迎です。

ベン

4

0 に答える 0