I have an Aspnet Web API project. I used repository pattern and I want to do dependency injection with ninject, but it's not working.
Ninject.Web.Common.cs
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(ProjectName.API.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(ProjectName.API.App_Start.NinjectWebCommon), "Stop")]
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IFirstService>().To<ServiceManager>().WithConstructorArgument("firstServiceDAL", new EFFirstDAL());
}
}
Is Ninject.Web.Common class correct? Because it isn't working.
My api's response;
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred when trying to create a controller of type 'FirstController'. Make sure that the controller has a parameterless public constructor.",
"ExceptionType": "System.InvalidOperationException",
FirstController.cs - My controller's constructor
public class FirstController : ApiController
{
private readonly IFirstService _firstService;
public FirstController(IFirstService firstService)
{
this._firstService = firstService;
}
}
What can I do ?
It seems that you don't have a public parameterless constructor.Your FirstController has to have a public,parameterless default constructor.
Add following code into your FirstController.
public FirstController()
{
}
It would be better if you had shared your controller.
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IFirstService>().To<FirstService>();
}
Related
void CallBackVerifiedResponse(OAuthAccessToken at, TwitterResponse response)
{
if (at != null)
{
SerializeHelper.SaveSetting<TwitterAccess>("TwitterAccess", new TwitterAccess
{
AccessToken = at.Token,
AccessTokenSecret = at.TokenSecret,
ScreenName = at.ScreenName,
UserId = at.UserId.ToString()
});
}
}
private void ok_Click_1(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(pinText.Text))
MessageBox.Show("Please enter PIN");
else
{
try
{
var cb = new Action<OAuthAccessToken, TwitterResponse>(CallBackVerifiedResponse);
service.GetAccessToken(_requestToken, pinText.Text, CallBackVerifiedResponse);
}
catch
{
MessageBox.Show("Something is wrong with the PIN. Try again please.", "Error", MessageBoxButton.OK);
}
}
}
My problem in is here when I use NavigationService.GoBack() inside the CallBackVerifiedResponse method i'm getting unauthorized access exception, and if i use it inside of the click event, I CallBackVerifiedResponse is not triggered. Any ideas?
It's been solved by using UIThread
public static class UIThread
{
private static readonly Dispatcher Dispatcher;
static UIThread()
{
// Store a reference to the current Dispatcher once per application
Dispatcher = Deployment.Current.Dispatcher;
}
/// <summary>
/// Invokes the given action on the UI thread - if the current thread is the UI thread this will just invoke the action directly on
/// the current thread so it can be safely called without the calling method being aware of which thread it is on.
/// </summary>
public static void Invoke(Action action)
{
if (Dispatcher.CheckAccess())
action.Invoke();
else
Dispatcher.BeginInvoke(action);
}
}
After this static class
I have called it inside of
CallBackVerifiedResponse
like this
UIThread.Invoke(()=>NavigationService.GoBack());
You can use Dispatcher.BeginInvoke to access the UIThread
Dispatcher.BeginInvoke(() =>
{
NavigationService.GoBack();
});
Or you could use your own smart dispatcher, used like this:
SmartDispatcher.BeginInvoke(() =>
{
MissionAccomplished();
});
Coded something as the following:
{
using System.ComponentModel;
using System.Windows.Threading;
using System.Windows;
using System;
public static class SmartDispatcher
{
/// <summary>
/// A single Dispatcher instance to marshall actions to the user
/// interface thread.
/// </summary>
private static Dispatcher _instance;
/// <summary>
/// Backing field for a value indicating whether this is a design-time
/// environment.
/// </summary>
private static bool? _designer;
/// <summary>
/// Requires an instance and attempts to find a Dispatcher if one has
/// not yet been set.
/// </summary>
private static void RequireInstance()
{
if (_designer == null)
{
_designer = DesignerProperties.IsInDesignTool;
}
// Design-time is more of a no-op, won't be able to resolve the
// dispatcher if it isn't already set in these situations.
if (_designer == true)
{
return;
}
// Attempt to use the RootVisual of the plugin to retrieve a
// dispatcher instance. This call will only succeed if the current
// thread is the UI thread.
try
{
_instance = Application.Current.RootVisual.Dispatcher;
}
catch (Exception e)
{
throw new InvalidOperationException("The first time SmartDispatcher is used must be from a user interface thread. Consider having the application call Initialize, with or without an instance.", e);
}
if (_instance == null)
{
throw new InvalidOperationException("Unable to find a suitable Dispatcher instance.");
}
}
/// <summary>
/// Initializes the SmartDispatcher system, attempting to use the
/// RootVisual of the plugin to retrieve a Dispatcher instance.
/// </summary>
public static void Initialize()
{
if (_instance == null)
{
RequireInstance();
}
}
/// <summary>
/// Initializes the SmartDispatcher system with the dispatcher
/// instance.
/// </summary>
/// <param name="dispatcher">The dispatcher instance.</param>
public static void Initialize(Dispatcher dispatcher)
{
if (dispatcher == null)
{
throw new ArgumentNullException("dispatcher");
}
_instance = dispatcher;
if (_designer == null)
{
_designer = DesignerProperties.IsInDesignTool;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static bool CheckAccess()
{
if (_instance == null)
{
RequireInstance();
}
return _instance.CheckAccess();
}
/// <summary>
/// Executes the specified delegate asynchronously on the user interface
/// thread. If the current thread is the user interface thread, the
/// dispatcher if not used and the operation happens immediately.
/// </summary>
/// <param name="a">A delegate to a method that takes no arguments and
/// does not return a value, which is either pushed onto the Dispatcher
/// event queue or immediately run, depending on the current thread.</param>
public static void BeginInvoke(Action a)
{
if (_instance == null)
{
RequireInstance();
}
// If the current thread is the user interface thread, skip the
// dispatcher and directly invoke the Action.
if (_instance.CheckAccess() || _designer == true)
{
a();
}
else
{
_instance.BeginInvoke(a);
}
}
}
}
I'm having some difficulty using Ninject's InSingletonScope binding with Web Api RC. No matter how I create my binding, it looks like perhaps Web Api is handling scope/lifetime instead of Ninject.
I've tried a few variations on wiring up Ninject. The most common is identical to the answer here:
ASP.NET Web API binding with ninject
I've also tried this version:
http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/
In both, I'm literally creating an out of the box Web Api project, then adding the Ninject packages as described in either post. Finally, I'm adding the Resolver and Scope classes, such as this for the StackOverflow version:
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void Dispose()
{
IDisposable disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.GetAll(serviceType);
}
}
and:
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
Then, NinjectWebCommon looks like this:
using System.Web.Http;
using MvcApplication2.Controllers;
[assembly: WebActivator.PreApplicationStartMethod(typeof(MvcApplication2.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(MvcApplication2.App_Start.NinjectWebCommon), "Stop")]
namespace MvcApplication2.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
// Register Dependencies
RegisterServices(kernel);
// Set Web API Resolver
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ILogger>().To<Logger>().InSingletonScope();
}
}
}
The ILogger and Logger objects don't do anything, but illustrate the issue. Logger does Debug.Writeline so that I can see when it was instantiated. And each refresh of the page shows that it's being refreshed per call, rather than the singleton I'd hoped for. Here is a controller using the Logger:
public class ValuesController : ApiController
{
private readonly ILogger _logger;
public ValuesController(ILogger logger)
{
_logger = logger;
_logger.Log("Logger created at " + System.DateTime.Now.ToLongTimeString());
}
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post(string value)
{
}
// PUT api/values/5
public void Put(int id, string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
When I put trace information into the creation of the kernel, it seems to show that the kernel is only created once. So... what am I not seeing? Why isn't the singleton persisted?
use
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel);
}
and don't dispose the kernel in the NinjectDependencyScope
#Remo Gloor
When I run your code in InMemoryHost of WebAPI and run Integration tests everything works fine and I do have singleton.
If I run WebAPI solution inside VS Cassini web server first run is successful
and when I click refresh I receive exception :
Error loading Ninject component ICache
No such component has been registered in the kernel's component container.
If I return old code with BeginBlock it works in Cassini but IsSingleton not working anymore in integration tests.
Instead of not disposing the kernel (which will not call the internal dispose) you can simply implement your own singleton:
public static class NinjectSingletonExtension
{
public static CustomSingletonKernelModel<T> SingletonBind<T>(this IKernel i_KernelInstance)
{
return new CustomSingletonKernelModel<T>(i_KernelInstance);
}
}
public class CustomSingletonKernelModel<T>
{
private const string k_ConstantInjectionName = "Implementation";
private readonly IKernel _kernel;
private T _concreteInstance;
public CustomSingletonKernelModel(IKernel i_KernelInstance)
{
this._kernel = i_KernelInstance;
}
public IBindingInNamedWithOrOnSyntax<T> To<TImplement>(TImplement i_Constant = null) where TImplement : class, T
{
_kernel.Bind<T>().To<TImplement>().Named(k_ConstantInjectionName);
var toReturn =
_kernel.Bind<T>().ToMethod(x =>
{
if (i_Constant != null)
{
return i_Constant;
}
if (_concreteInstance == null)
{
_concreteInstance = _kernel.Get<T>(k_ConstantInjectionName);
}
return _concreteInstance;
}).When(x => true);
return toReturn;
}
}
And then simply use:
i_Kernel.SingletonBind<T>().To<TImplement>();
Rather then
i_Kernel.Bind<T>().To<TImplement>().InSingletonScope();
note: although it is only matters for the first request, this implementation is not thread safe.
I want to try out so SOA style logging using Snap in my MVC3 application. I'm using Ninject for IoC so have installed Ninject.MVC and Snap.Ninject via Nuget all had a look at the sample code in GitHub for Snap.Ninject. I also read Getting SNAP(AOP), NInject and ASP.Net MVC 3 working together
which seems to be doing exactly what I want.
I've updated my NinjctMVC3.cs accordingly but when I add the interceptor attribute to my method, I get an object ref error from Snap AspectUtility. Here is my NinjectMVC3.cs
public static class NinjectMVC3 {
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start() {
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop() {
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel() {
//var kernel = new StandardKernel();
NinjectAopConfiguration.NinjectAopConfigure();
var kernel = NinjectAopConfiguration._container.Kernel;
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel) {
kernel.Bind<ILogger>().To<NLogger>()
.WithConstructorArgument("currentClassName", x => x.Request.ParentContext.Request.Service.FullName); ;
kernel.Bind<ISomeDataFactory>().To<SomeDataFactory>();
}
}
public static class NinjectAopConfiguration {
public readonly static NinjectAspectContainer _container;
static NinjectAopConfiguration() {
_container = new NinjectAspectContainer();
}
public static void NinjectAopConfigure() {
SnapConfiguration.For(_container).Configure(c => {
c.IncludeNamespace("TestAopLogging.Model.*");
c.Bind<MyMethodInterceptor>().To<MyInterceptorAttribute>();
});
}
}
public class MyMethodInterceptor : MethodInterceptor {
public override void InterceptMethod(Castle.DynamicProxy.IInvocation invocation, MethodBase method, System.Attribute attribute) {
var logger = new NLogger(method.DeclaringType.ToString());
logger.LogInfo("Hello AOP Logger. Your method (" + method.Name + ") has been intercepted");
invocation.Proceed();
}
public override void BeforeInvocation() {
var logger = new NLogger("How do I work out what class I'm in?");
base.BeforeInvocation();
}
public override void AfterInvocation() {
var logger = new NLogger("How do I work out what class I'm in?");
logger.LogInfo("Hello AOP Logger. After Invocation");
base.AfterInvocation();
}
}
public class MyInterceptorAttribute : MethodInterceptAttribute { }
And the controller
public class HomeController : Controller
{
private ILogger _logger;
private ISomeDataFactory _someDataFactory;
public HomeController(ILogger logger, ISomeDataFactory someDataFactory) {
_logger = logger;
_someDataFactory = someDataFactory;
}
public ActionResult Index()
{
_logger.LogInfo("I've hit the index action");
_someDataFactory.GetStuffAndLogTheOldWay();
_someDataFactory.GetStuffAndLogUsingAOP();
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
}
and the factory class with the method with the intercept attribute
public interface ISomeDataFactory {
string GetStuffAndLogTheOldWay();
string GetStuffAndLogUsingAOP();
}
public class SomeDataFactory : ISomeDataFactory {
private ILogger _logger;
public SomeDataFactory(ILogger logger) {
_logger = logger;
}
public string GetStuffAndLogTheOldWay() {
_logger.LogInfo(MethodBase.GetCurrentMethod().Name + " was called");
return "I called GetStuffAndLogTheOldWay";
}
[MyInterceptor] // If I comment this out, then all is good
public string GetStuffAndLogUsingAOP() {
return "I called GetStuffAndLogUsingAOP";
}
}
and this results in the following exception
[NullReferenceException: Object reference not set to an instance of an object.]
Snap.AspectUtility.CreateProxy(Type interfaceType, Object instanceToWrap, IInterceptor[] interceptors) +29
Snap.AspectUtility.CreatePseudoProxy(IMasterProxy proxy, Type interfaceType, Object instanceToWrap) +184
Snap.Ninject.AspectProxyActivationStrategy.Activate(IContext context, InstanceReference reference) +376
Ninject.Activation.<>c__DisplayClass2.b__0(IActivationStrategy s) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Pipeline.cs:58
Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable1 series, Action1 action) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:23
Ninject.Activation.Pipeline.Activate(IContext context, InstanceReference reference) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Pipeline.cs:58
Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Context.cs:182
Ninject.KernelBase.b__7(IContext context) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\KernelBase.cs:375
System.Linq.<>c__DisplayClass123.<CombineSelectors>b__11(TSource x) +32
System.Linq.WhereSelectEnumerableIterator2.MoveNext() +151
System.Linq.Enumerable.SingleOrDefault(IEnumerable1 source) +4178557
Ninject.Planning.Targets.Target1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Planning\Targets\Target.cs:179
Ninject.Planning.Targets.Target1.ResolveWithin(IContext parent) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Planning\Targets\Target.cs:147
Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:97
Ninject.Activation.Providers.<>c__DisplayClass2.<Create>b__1(ITarget target) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:81
System.Linq.WhereSelectArrayIterator2.MoveNext() +85
System.Linq.Buffer1..ctor(IEnumerable1 source) +325
System.Linq.Enumerable.ToArray(IEnumerable1 source) +78
Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:81
Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Context.cs:157
Ninject.KernelBase.<Resolve>b__7(IContext context) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\KernelBase.cs:375
System.Linq.<>c__DisplayClass123.b__11(TSource x) +32
System.Linq.WhereSelectEnumerableIterator2.MoveNext() +151
System.Linq.Enumerable.SingleOrDefault(IEnumerable1 source) +4178557
Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) in c:\Projects\Ninject\Maintenance2.2\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs:56
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +51
Thanks in advance. I want a working demo of it failing then let me know.
Thanks to Tyler Brinks for spotting my typo!
Update the namespace reference to
c.IncludeNamespace("TestAopLogging.Models.*");
and all is well.
Hope someone finds this useful.
I have no idea why my action is not being hit. This controller is under an "Area" called api.
$.ajax({
url: defaults.url + (defaults.url.indexOf('?') > 0 ? '&' : '?') + 'r=' + Math.random(),
type: defaults.method,
contentType: 'application/json',
dataType: 'json',
data: defaults.data,
success: function (data) {
public class EventController : Controller
{
[JsonpFilter(Order = 1)]
public JsonResult Register()
{
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new ApiRegistrationResponse()
};
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class JsonpFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext == null)
throw new ArgumentNullException("filterContext");
string callback = filterContext.HttpContext.Request.QueryString["callback"];
if (!string.IsNullOrEmpty(callback))
{
var result = filterContext.Result as JsonResult;
if (result == null)
{
throw new InvalidOperationException("JsonpFilterAttribute must be applied only " +
"on controllers and actions that return a JsonResult object.");
}
filterContext.Result = new JsonpResult
{
ContentEncoding = result.ContentEncoding,
ContentType = result.ContentType,
Data = result.Data,
Callback = callback
};
}
}
}
After trial and error I had to exclude the following ninject file NinjectMVC3.cs under the App_Start folder and it started working.
[assembly: WebActivator.PreApplicationStartMethod(typeof(MvcApplication2.App_Start.NinjectMVC3), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(MvcApplication2.App_Start.NinjectMVC3), "Stop")]
namespace MvcApplication2.App_Start
{
using System.Reflection;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Mvc;
public static class NinjectMVC3
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
}
}
}
Hello am an trying to implement a global filter with injection.
The filter looks like this.
public class WikiFilter : IActionFilter
{
private IWikiService service;
public WikiFilter(IWikiService service)
{
this.service = service;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
!!!Code here!!
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
throw new NotImplementedException();
}
}
And i have attached the filter with injection the following way in my global.asax.
public class MvcApplication : System.Web.HttpApplication,
IAuthenticationApplication<User>
{
protected void Application_Start()
{
Ninject();
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
RegisterGlobalFilters(GlobalFilters.Filters);
}
private void Ninject()
{
// Create Ninject DI kernel
IKernel kernel = new StandardKernel();
kernel.Bind<DataContext>().ToSelf().InRequestScope();
kernel.Bind<IWikiRepository>().To<WikiRepository>();
kernel.Bind<IWikiService>().To<WikiService>();
// Global filters
kernel.BindFilter<WikiFilter>(FilterScope.Global, 0);
DependencyResolver.SetResolver
(new NinjectDependencyResolver(kernel));
}
}
But for some reason is the filter never fired when the application runs, have i not implemented it correctly?
I would recommend you using the ~/App_Start/NinjectMVC3.cs file to configure the Ninject kernel:
[assembly: WebActivator.PreApplicationStartMethod(typeof(AppName.App_Start.NinjectMVC3), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(AppName.App_Start.NinjectMVC3), "Stop")]
namespace AppName.App_Start
{
using System.Web.Mvc;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Mvc;
using Ninject.Web.Mvc.FilterBindingSyntax;
public static class NinjectMVC3
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<DataContext>().ToSelf().InRequestScope();
kernel.Bind<IWikiRepository>().To<WikiRepository>();
kernel.Bind<IWikiService>().To<WikiService>();
kernel.BindFilter<WikiFilter>(FilterScope.Global, 0);
}
}
}
and the Global.asax stays unchanged. By the way that's the default setup when you install the Ninject.MVC3 NuGet package.