我正在使用Castle Windsor中的这个(http://docs.castleproject.org/Windsor.Windsor-Tutorial-Part-Five-Adding-logging-support.ashx)IoC教程,我已经通过了所有前面的步骤,如上所述,我试图通过属性将log4net记录器注入我的控制器,如下:
public class HomeController : Controller
{
// this is Castle.Core.Logging.ILogger, not log4net.Core.ILogger
public ILogger Logger { get; set; }
public ActionResult Index()
{
Logger.Debug("Hello world");
ViewBag.Message = "Hello world";
return View();
}
}
但遗憾的是在执行Logger.Debug
时,Logger为null,因此结果为null引用异常。虽然我正打算打电话
var logger = container.Resolve<ILogger>();
logger.Debug("Container bootstrapped");
在Global.asax记录器中完全解析。
为什么Windsor不想解决控制器内的依赖?
修改
控制器是通过温莎创建的
Global.asax中
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Castle.Core.Logging;
using Castle.Windsor;
using Castle.Windsor.Installer;
using FlightManagementSystem.WebPlatform.Configuration.IoC.Windsor.Factories;
namespace FlightManagementSystem.WebPlatform
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
private static IWindsorContainer container;
protected void Application_Start()
{
Debugger.Break();
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
container = new WindsorContainer();
container.Install(FromAssembly.This());
var controllerFactory = new ControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
protected void Application_End()
{
container.Dispose();
}
}
}
ControllerFactory.cs
using System;
using System.Web;
using System.Web.Mvc;
using Castle.MicroKernel;
namespace FlightManagementSystem.WebPlatform.Configuration.IoC.Windsor.Factories
{
public class ControllerFactory : DefaultControllerFactory
{
private readonly IKernel kernel;
public ControllerFactory(IKernel kernel)
{
this.kernel = kernel;
}
public override void ReleaseController(IController controller)
{
kernel.ReleaseComponent(controller);
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, String.Format(Resources.THE_CONTROLLER_FOR_PATH_0_COULD_NOT_BE_FOUND, requestContext.HttpContext.Request.Path));
}
return (IController) kernel.Resolve(controllerType);
}
}
}
ControllerInstaller.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace FlightManagementSystem.WebPlatform.Configuration.IoC.Windsor.Installers
{
public class ControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register
(
Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient()
);
}
}
}
LoggerInstaller.cs
using Castle.Facilities.Logging;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace FlightManagementSystem.WebPlatform.Configuration.Logger.log4net
{
public class LoggerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<LoggingFacility>(f => f.UseLog4Net());
}
}
}
答案 0 :(得分:3)
这不是你问题的真正答案,而是一些建议:
1)在记录时使用空对象模式来阻止NRE
:
ILogger logger = NullLogger.Instance;
public ILogger Log
{
get { return logger; }
set { logger = value ?? NullLogger.Instance; }
}
2)在大多数情况下,应首先添加记录工具 - 在任何安装人员注册之前:
container = new WindsorContainer();
container.AddFacility<LoggingFacility>(f => f.UseLog4Net());
container.Install(FromAssembly.This());
如果您稍后添加日志记录工具,则可能会在安装过程中丢失一些有价值的消息。