Using the Ninject NLogModule Logger in global.asax - ninject

I'm using Ninject for DI in my asp.net application, so my Global class inherits from NinjectHttpApplication.
In my CreateKernel(), I'm creating my custom modules and DI is working fine for me.
However, I notice that there is a Logger property in the NinjectHttpApplication class, so I'm trying to use this in Application_Error whenever an exception is not caught.
I think I'm creating the nlog module correctly for Ninject, but my logger is always null. Here's my CreateKernel:
protected override Ninject.Core.IKernel CreateKernel()
{
IKernel kernel = new StandardKernel(new NLogModule(), new NinjectRepositoryModule());
return kernel;
}
But in the following method, Logger is always null.
protected void Application_Error(object sender, EventArgs e)
{
Exception lastException = Server.GetLastError().GetBaseException();
Logger.Error(lastException, "An exception was caught in Global.asax");
}
To clarify, Logger is a property on NinjectHttpApplication of type ILogger and has the [Inject] attribute
Any idea how to inject correctly into Logger?

Download the latest version from GitHub. The logging was removed. The reason you are not seeing the logger injected is that Ninject isn't creating the HttpApplication class, so it doesn't know to inject it, you have to assign it manually. Ninject can only initialize components activated by the kernel.

Are you actually wiring up an ILogger in your NLogModule? If not then Ninject probably won't know what to use when you use the Logger of your implemented NinjectHttpApplication class.
I would check what is in your NLogModule, and I would also suggest putting it in your question. I think it might help us to solve your problem.

Related

Replace the injected HttpContext for class in application

I'm setting up some integration tests for mediatr handlers using xunit, respawn, and webapplicationfactory....
One of classes ultimately called by the mediatr handler that is being tested.. has a dependency on IHttpContextAccessor as you can see below
I feel like I've set up the "replacement" singleton that I want injected correctly as per below:
But when the integration test runs.. the httpContextAccessor is not null but the HttpContext is ALWAYS null.
I've tried about 6 million things :( Much sadness.
How can get the IHttpContextAccessor to resolve correctly to what I'm setting in ConfigureServices?
When the integration test runs.. the httpContextAccessor is not null but the HttpContext is ALWAYS null.How can get the IHttpContextAccessor to resolve correctly to what I'm
setting in ConfigureServices?
No we cannot, The HttpContext will only be available within the scope of the request because ConfigureServices invocked before constructing Startup so if we try to inject, it will through exception, even if we declare at global variable in that scenario it will always be null. Application startup happens only once, and long before any request has been received.
Let's try to access it within IConfiguration as following:
public Startup(IConfiguration configuration,IHttpContextAccessor httpContextAccessor)
{
Configuration = configuration;
HttpContextAccessor = httpContextAccessor;
}
public IConfiguration Configuration { get; }
public IHttpContextAccessor HttpContextAccessor { get; }
Output:
As you can see, it doesn't allow us to do so.
Even if we try to inject it within configuration itself it will ended up with following exception:
Therefore, ConfigureServices runs once before any httprequest coming to application. If we forcefully try to call it outside of request life-cycle it will always ended up with NullReferenceException. You can get more details in the official document.
In addition to this, we can inject service reference within configuration as following:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
I needed to implement IHttpContextAccessor myself
Then utilise in the ConfigureTestServices of the WebApplicationFactory ConfigureWebHost

EJB Singleton service fails at deploy

I'm rather newbie to JBoss and annotations. I have following code example. Irrelevant details are cutted out.
#Singleton
#Startup
public class SomeBean {
#Resource
TimerService timerService;
#Inject
AnotherSingleton anotherOne;
Timer timer;
#PostConstruct
private void ejbCreate() {
timer = timerService.createIntervalTimer(0, interval, tc);
}
#Timeout
public void run() throws Exception {
}
}
#Singleton
public class AnotherSingleton {
#Inject
Repository rep;
}
There is case that when war is deploying on JBoss it fails with exception from Repository producer (service in another Jboss is not available).
Caused by: java.lang.IllegalStateException: WFLYEE0042: Failed to construct component instance
So process ends with
WFLYCTL0186: Services which failed to start: service jboss.deployment.unit."someservices-view.war".component.SomeBean.START
What options do i have?
Can i tell JBoss to don't #Inject beans on startup but when code is executed by timer?
Can i somehow catch exception?
#Schedule is out of question becaouse i need to configure Timer.
Injections are handled by the CDI specification which provides a feature to "wrap" injections as it were, like so.
#Inject
Instance<AnotherSingleton> anotherOneInstance;
This basically creates a proxy around the AnotherSingleton and you can delay obtaining an actual reference to it at the time that you need it.
AnotherSingleton anotherOne = anotherOneInstance.get();
This should allow deployment to succeed and your timer to initialize, but of course if at the moment you attempt to use anotherOne and the repository is not available, the code will still break with an exception.
Alternatively, you can always do a manual lookup through the BeanManager to not have to rely on any form of dependency injection, but that should always be a last resort as it just leads to cumbersome code.

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

Ninject interception WCF service

I'm a newbie on the subject, so I'll try to make this as clear as I can...
I created a WcfModule, where I load the following package:
Bind<IDistributorService>().To<DistributorService>().InRequestScope().Intercept().With<ExceptionInterceptor>();
At first, I don't receive any error, but I put an InterceptAttribute on my function:
[AttributeUsage(AttributeTargets.Method)]
public sealed class HandleExceptionsAttribute : InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Kernel.Get<ExceptionInterceptor>();
}
}
[HandleExceptions]
public virtual Result<List<DistributorDataContract>> GetDistributor(string id)
{
//...code...
I get an error in this function: (first line in method)
private ServiceHost CreateNewServiceHost(Type serviceType, Uri[] baseAddresses, WebHttpBehavior webBehavior, WebHttpBinding webHttpBinding)
{
var host = base.CreateServiceHost(serviceType, baseAddresses);
//...
}
With the error:
InvalidProxyConstructorArgumentsException was unhandled by user code
Can not instantiate proxy of class:
My.Namespace.DistributorService.
Could not find a parameterless constructor.
Anyone who knows what the problem could be? Thanks!
This exception is thrown by castle core dynamic proxy when it is instructed to create a "class proxy" which does not have a parameterless (default) constructor and no constructor-arguments are passed to castle (see source).
My best guess is, that when you use ninject interception by attributes, ninject will instruct castle core to create a class-proxy, no matter whether your binding is Bind<IFoo>().To<Foo>() or Bind<Foo>().ToSelf().
It seems a bit strange, however, that ninject is not resolving and passing along all required constructor parameters.
What is the implementation of DistributorService and what's the implementation of the base class of the class containing CreateNewServiceHost?
Workaround:
Of course, switching to the Intercept().With<TInterceptor>() syntax will probably also enable you to use interception (see http://codepyre.com/2010/03/using-ninject-extensions-interception-part-2-working-with-interceptors/)

ServiceLocator does not exist in Ninject?

I am trying to use Ninject with Common Service Locator in my asp.net mvc3 project. I've added Ninject.dll and CommonServiceLocator.NinjectAdapter.dll to the project.
I wrote following code in my global.asax.cs file.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(CreateKernel()));
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
private static IKernel CreateKernel()
{
IKernel kernel = new StandardKernel();
kernel.Bind(typeof(IUserService)).To(typeof(UserService));
return kernel;
}
But it does not compile because it couldn't find ServiceLocator and giving me the error
"The name 'ServiceLocator' does not exist in the current context"
What am I doing wrong here? Am I missing a reference?
I think you won't get an answer to your question because using the Common ServiceLocator is very uncommon especially for MVC3. The service locator anti-pattern you seem to use is considered bad practice.
Almost everyone is using some IDependencyResolver implementation instead. See https://github.com/ninject/ninject.web.mvc/wiki/MVC3