使用 Autofac 将 log4net 注入控制器

发布于 2024-11-27 12:00:55 字数 2031 浏览 0 评论 0原文

尝试使用 Autofac 将 log4net 类注入我的控制器,但出现以下异常:

未找到带有“公共绑定标志”的构造函数 可以使用可用的服务和参数调用类型“MvcApplication6.Controllers.HomeController”:无法解析构造函数“Void .ctor(log4net.ILog)”的参数“log4net.ILog logger”。

我创建了一个模块来使用正确的类型注入 Log 类:

public class LogInjectionModule : Module
{
    protected override void AttachToComponentRegistration(IComponentRegistry registry, IComponentRegistration registration)
    {
         registration.Preparing += OnComponentPreparing;
    }

    static void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        var t = e.Component.Activator.LimitType;
        e.Parameters = e.Parameters.Union(new[] 
        { 
            new ResolvedParameter((p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(t)) 
        });
    }
}

然后我在 ASP.NET MVC Application_Start 方法中注册该模块:

protected void Application_Start()
{
     ContainerBuilder builder = new ContainerBuilder();
     builder.RegisterControllers(typeof (MvcApplication).Assembly) ;

     var container = builder.Build() ;
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

     builder.RegisterModule(new LogInjectionModule());

     AreaRegistration.RegisterAllAreas();

     RegisterGlobalFilters(GlobalFilters.Filters);
     RegisterRoutes(RouteTable.Routes);
}

我已向以 ILog 作为参数的控制器:

namespace MvcApplication6.Controllers
{
   public class HomeController : Controller
   {
      ILog _log;

      public HomeController(ILog logger) 
      {
         _log = logger;
      }

      public ActionResult Index()
      {
         ViewBag.Message = "Welcome to ASP.NET MVC!";

         _log.Info("Log message from Index()");

         return View();
      }

      public ActionResult About()
      {
         _log.Info("Log message from About()");

         return View();
      }
   }
}

我确信我错过了一个步骤,所以任何帮助将不胜感激。

Trying to use Autofac to inject a log4net class into my controller, but I get the following exception:

None of the constructors found with 'Public binding flags' on
type 'MvcApplication6.Controllers.HomeController' can be invoked with the available services and parameters: Cannot resolve parameter 'log4net.ILog logger' of constructor 'Void .ctor(log4net.ILog)'.

I have created a module to inject the Log class using the correct type:

public class LogInjectionModule : Module
{
    protected override void AttachToComponentRegistration(IComponentRegistry registry, IComponentRegistration registration)
    {
         registration.Preparing += OnComponentPreparing;
    }

    static void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        var t = e.Component.Activator.LimitType;
        e.Parameters = e.Parameters.Union(new[] 
        { 
            new ResolvedParameter((p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(t)) 
        });
    }
}

I then register the module within my ASP.NET MVC Application_Start method:

protected void Application_Start()
{
     ContainerBuilder builder = new ContainerBuilder();
     builder.RegisterControllers(typeof (MvcApplication).Assembly) ;

     var container = builder.Build() ;
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

     builder.RegisterModule(new LogInjectionModule());

     AreaRegistration.RegisterAllAreas();

     RegisterGlobalFilters(GlobalFilters.Filters);
     RegisterRoutes(RouteTable.Routes);
}

I have added a constuctor to the controller which takes an ILog as a parameter:

namespace MvcApplication6.Controllers
{
   public class HomeController : Controller
   {
      ILog _log;

      public HomeController(ILog logger) 
      {
         _log = logger;
      }

      public ActionResult Index()
      {
         ViewBag.Message = "Welcome to ASP.NET MVC!";

         _log.Info("Log message from Index()");

         return View();
      }

      public ActionResult About()
      {
         _log.Info("Log message from About()");

         return View();
      }
   }
}

I am sure I have missed a step, so any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嗳卜坏 2024-12-04 12:00:55

我不确定这是否会导致您的问题,但您应该尝试在调用 builder.Build(); 之前将模块添加到 ContainerBuilder;

像这样的事情:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterControllers(typeof (MvcApplication).Assembly) ;
builder.RegisterModule(new LogInjectionModule());

var container = builder.Build() ;
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

另一个建议是不要注入记录器。通常,当我设计一个类时,我会尝试使用构造函数依赖项来表达我正在建模的组件的逻辑业务依赖项。日志记录主要是与应用程序正交的实现细节。至少使用 log4net,您可以在任何需要使用 LogManager.GetLogger(type) 创建的日志记录的类中拥有静态成员。为了方便添加记录器,您可以使用 Visual Studio 代码片段。

I'm not sure this is causing your problem but you should try to add the module to the ContainerBuilder before calling builder.Build();

Something like this:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterControllers(typeof (MvcApplication).Assembly) ;
builder.RegisterModule(new LogInjectionModule());

var container = builder.Build() ;
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

Another suggestion is to not inject the logger. Usually when i design a class, with the constructor dependencies i try to express the logical business dependencies of the component i'm modelling. Logging is mostly an implementation detail that is orthogonal to the application. At least with log4net you can have a static member in any class where you need logging that is created with LogManager.GetLogger(type). To facilitate adding the logger you can use a Visual Studio snippet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文