我正在研究这个(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 的执行点Logger.Debug
为空,因此导致空引用异常。虽然当我试图打电话时
var logger = container.Resolve<ILogger>();
logger.Debug("Container bootstrapped");
Global.asax 记录器内部已完美解决。
为什么 Windsor 不想解决控制器内部的依赖关系?
编辑
控制器是通过 Windsor 创建的
全球.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();
}
}
}
控制器工厂.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);
}
}
}
控制器安装程序.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());
}
}
}