1

I have an MVC4 site that uses both MVC and WebAPI in it. All was going well till I tried to change my classes to have a cross cutting AOP class that would help with caching data. I am now finding that when I call a method that does not have the InterceptAttribute on it, it will crash because Ninject didn't inject with a parameter, and it fails.

My BLL class looks like this:

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
}

My WebApi Controller looks like this:

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
}

In my Website, I created the following Ninject classes for resolving the controllers:

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);
    }
}

In Global.asax I then register this resolver:

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));

Things were fine till I added the attribute Cache using Ninject.Extensions.Interception.Attributes.InterceptAttribute.

The class now looks like this (note that I added a parameterless constructor and marked one of the methods as virtual, these are both required for the Interception to work):

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
}

Now on the WebAPI controller, when I call GetToBars(the method with the Intercept Attribute), everything still works fine.

However, when I call GetAllBars(the method that doesn't have the Intercept Attribute), I fail with an exception that _context is null.

Any help would be greatly appreciated.

Ben

Ben Haynie
  • 115
  • 9
  • lots of people dont like the [regions](https://lostechies.com/jimmybogard/2007/12/06/don-t-hide-the-ugly/), at least when your posting here you should remove them. Code you post here should not be long enough to require regions - and the browser/website doesn't support collapsing them anyway. So it's just noise. – BatteryBackupUnit Apr 16 '15 at 05:09

0 Answers0