Why is Ninject interceptor not called? - module

Quick question - I can't figure out the following:
I've written a Ninject module:
public void OnLoad(IKernel kernel)
{
kernel.Bind<GenericRepository>()
.ToConstructor(syntax => new GenericRepository(new DbContext()))
.Intercept()
.With<LogInterceptor>();
}
I've got an interceptor:
public void Intercept(IInvocation invocation)
{
invocation.proceed();
}
Application builds, module is loaded, the repository returns entities, however - If I put a breakpoint in the interceptor, it is never called.
Any ideas?

If I remember correctly, Ninject interception relies on Castle Proxy technology... so it can only work with virtual members.

Related

Global.asax's Application_Start method doesn't get called

I have a WCF web service hosted on my Local IIS (not Express). I've included a Global.asax in its root directory, where it is supposed to be. Since I'm using Ninject with WCF extensions, the class Global extends NinjectHttpApplication instead of HttpApplication (as seen here).
Also, I'm using the AutoMapper library in order to circumvent writing boring boilerplate code.
The problem arises because a static method I defined for configuring AutoMapper isn't being called causing AutoMapper to throw exceptions when I call Mapper.Map(). That static method's call is defined in Global.asax's Application_Start() method since I want these mappings to be performed once per the web service's lifetime.
Ninject's CreateKernel() method gets called just fine, by the way.
Am I missing something here? I've tried debugging it, it doesn't hit the breakpoint even though I've attached the debugger to w3wp.exe and also tried putting an explicit Debugger.Break() call in its body.
This is how it looks like so far:
Global.asax
<%# Application Codebehind="Global.asax.cs" Inherits="MyApp.WebHost.Global" Language="C#" %>
Global.asax.cs
public class Global : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel();
/* various bindings */
return kernel;
}
protected void Application_Start(object sender, EventArgs e)
{
AutoMapperConfig.RegisterMappings();
}
/* rest of Global.asax methods (Session_Start, Application_BeginRequest, etc.) with empty bodies */
RegisterMappings method
public static class AutoMapperConfig
{
public static void RegisterMappings()
{
/* multiple calls to Mapper.CreateMap() */
Mapper.AssertConfigurationIsValid();
}
}
Svc file markup
<%# ServiceHost Language="C#"
Debug="true"
Service="MyApp.Services.MyAppService"
Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" %>
Everything else works, I've already created a test client (a simple console app) and added a service reference. Service methods get called just fine, it is just that these mappings are a bit problematic since AutoMapper keeps throwing AutoMapperMappingException exceptions ("Missing type map configuration or unsupported mapping.") for the obvious reasons.
The application's app pool is DefaultAppPool. Should I create a separate one?
I really don't understand the problem here. Thank you in advance.
Well, it required some additional searching but I found the answer here - https://groups.google.com/forum/#!topic/ninject/wRy3ELSV4bU
The problem was that NinjectHttpApplication class itself implements the Application_Startup method so it is impossible to implement it in your own derived class (Global class).
To simulate such behavior one needs to override the OnApplicationStarted Ninject's method.
This is how it looks like regarding my particular problem:
protected override void OnApplicationStarted()
{
AutoMapperConfig.RegisterMappings();
}

Having trouble integrating Ninject

This one is driving me mad. I've read the Ninject docs, I've read the docs for the Ninject MVC extension, I've lost count of how many related SO questions I've read, and I have no idea where the problem is with my code.
I'm building a webapp in ASP.NET MVC 4, and I'm using Ninject to bind repository interfaces. The docs say that if you add Ninject using NuGet (which I did), then it wires everything up for you so you don't need to have your application inherit from NinjectHttpApplication (so I haven't) and you just need to add your bindings in NinjectWebCommon.RegisterServices(), (which I have). I have an IRepository<T>, and a Repository<T>. The user repository has a few extra methods for login and registration, so there's a separate UserRepository which implements IRepository<User>. My bindings therefore look like this:
kernel.Bind(typeof(IRepository<>)).To(typeof(BaseRepository<>)).InRequestScope();
kernel.Bind(typeof(IRepository<User>)).To(typeof(UserRepository)).InRequestScope();
The docs, and a couple of SO questions, also mention that if you added Ninject though NuGet (which I did) then it sorts out the controller factory for you and you don't need to implement your own Ninject-y controller factory (so I haven't). My controllers inherit from a BaseController, which has a constructor that accepts a set of IRepository-compatible repositories. Now, from what I've read, when I try to use a controller, Ninject should recognise the IRepositoriy parameters and provide them. It doesn't. Even if I put the [Inject] attribute on the constructor, it still gets ignored - the parameterless constructor gets called instead. If I remove the parameterless constructor, I get a compile error complaining that there isn't one.
What have I missed? How do I get Ninject to provide my repositories?
Weird, I am unable to reproduce the problem you are describing.
Steps:
Create a new ASP.NET MVC 4 application using the Internet template
Install the Ninject.MVC3 NuGet
Define some classes:
public interface IRepository<T>
{
}
public abstract class BaseRepository<T> : IRepository<T>
{
}
public class User
{
}
public class UserRepository : BaseRepository<User>
{
}
public abstract class BaseController<T>: Controller
{
protected BaseController(IRepository<T> repository)
{
this.Repository = repository;
}
protected IRepository<T> Repository { get; private set; }
}
public class HomeController : BaseController<User>
{
public HomeController(IRepository<User> repository): base(repository)
{
}
public ActionResult Index()
{
return Content(this.Repository.GetType().ToString());
}
}
And wire them up in ~/App_Start/NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel)
{
kernel
.Bind(typeof(IRepository<User>))
.To(typeof(UserRepository))
.InRequestScope();
}
Run the application and the proper instance of the repository gets injected into HomeContorller.

How to resolve dependency inside AuthorizeAttribute with WebApi and Ninject

My current setup is using Ninject for simple IoC, everything goes fine, but I'm not able to resolve one of the classes I need inside my AuthorizeAttribute. I need to access a class that does ClaimsVerification:
Here's my code:
IoC Config:
var kernel = new StandardKernel(); // Ninject IoC
// These registrations are "per instance request".
// See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/
kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()
.InSingletonScope();
kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();
kernel.Bind<ISmartDocumentorUow>().To<SmartDocumentorUow>();
kernel.Bind<IClaimsVerification>().To<ClaimsVerification>();
// kernel
//kernel.BindFilter<MyAuthorizeAttribute>(FilterScope.Controller, 0).WhenControllerHas<RequireRolesAttribute>();
// Tell WebApi how to use our Ninject IoC
config.DependencyResolver = new NinjectDependencyResolver(kernel);
MyAuthorizeAttribute:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
[Inject]
IClaimsVerification clamisverify { get; set; }
public MyAuthorizeAttribute()
{
//var x = System.Web.Mvc.DependencyResolver.Current.(typeof(IClaimsVerification));
}
Yap, sorry, the problem was injecting the iClaimsverification that isn't working in web api..
I tryed with the public property and still it didn't work.
the bindfilter is commented out, because it doesn't exist in the core NInject api (dll), it does exists in the MVC dll of ninject but it works for Action filters in the web mvc, and not in the api mvc for what i can tell..
i do solved the issue like this, though i don't like a lot of this fix:
private IClaimsVerification verifier
{
get
{
return (GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IClaimsVerification)) as IClaimsVerification);
}
}
The property you have marked with Inject is private - you need to initialize Ninject with a custom configuration to opt into what would be a much less efficient process
(You didnt state the problem in your question. I see you were trying BindFilter, but it's commented out (why?) - this is the correct approach. I recommend reading the Ninject.MVC3 wiki article on BindFilter for an example)

Upgrading Ninject/Ninject WCF Extensions to the latest version 3.0.0.5

I am currently using Ninject (2.2.1.4) and Ninject.Extensions.Wcf (2.2.0.4) with my WCF service. I would like to upgrade to Ninject (3.0.0.15) and Ninject.Extensions.Wcf (3.0.0.5) and it doesn't look like I can use my current approach anymore. Can anyone point me to some samples or posts on how to get the latest version of Ninject working with a WCF project.
My current approach:
I wrote a module:
public class NinjectDependencyResolver : NinjectModule
{
public override void Load()
{
// Declare bindings
}
}
I added the Factory Attribute to my .svc file
Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory"
I added a Global.asax to the WCF project
public class Global : NinjectWcfApplication
{
protected override IKernel CreateKernel()
{
return new StandardKernel(new NinjectDependencyResolver());
}
}
Now I can modify the default constructor in my service and use constructor injection.
Any pointers on how I could upgrade are appreciated.
Thanks
Add Ninject.Web.Common and derive from NinjectHttpApplication or use the App_Start file that comes with the NuGet package.

Ninject Interceptors

I'm developing a WPF desktop application with caliburn.micro framework, and I want to configure ninject interceptors so that I can intercept method calls. I would like to do this to handle exceptions in a centralized place, so that I don't have many try-catch blocks everywhere around my code.
I haven't been able to acomplish this, because everytime I wire everything up with ninject, the system throws an exception.
So here's some code:
The AppBootstrapper configure method looks like this:
protected override void Configure()
{
_kernel = new StandardKernel(new NinjectServiceModule());
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
_kernel.Bind<ISomeViewModel>().To<SomeViewModel>().Intercept().With<SomeInterceptor>() //this is where the exception is thrown;
_kernel.Bind<IShell>().To<ShellViewModel>();
}
Now the intercept method in my interceptor:
public void Intercept(IInvocation invocation)
{
if (invocation.Request.Method.Name == "TheMethodIWantIntercepted")
{
try
{
invocation.Proceed();
}
catch (Exception)
{
Console.WriteLine("I Handled exception");
}
}
else
{
invocation.Proceed();
}
}
The method in the view model looks like this:
public virtual void TheMethodIWantIntercepted()
{
//Some logic here
}
So that's how interceptors are supposed to work. But it doesn't work, everytime I run the program, and ninject tries to inject the instance of SomeViewModel into ISomeViewModel, the program execution fails, and this is the exception that is thrown (and the stack trace):
http://pastebin.com/qerZAjVr
Hope you can help me with this, thank you in advance.
You have to load either DynamicProxy(2)Module or LinFuModule depending on what proxy library you prefer.
Also be aware that Ninject 2.2 will create a class proxy for SomeViewModel which requires:
a parameterless constructor
virtual methods
Interface proxies don't have this restriction but this requires Ninject 3.0.0