当使用autofac,我怎么使用的WebAPI控制器类型名称作为参数传递给depencency的注册? [英] When using autofac, how do I use a WebAPI controller type name as a parameter to a depencency's Register?

查看:284
本文介绍了当使用autofac,我怎么使用的WebAPI控制器类型名称作为参数传递给depencency的注册?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用autofac并试图注册的WebAPI控制器。每个控制器都采用了一种独特 Logging.ILog 作为构造函数的参数(这是我的ILog适应log4net的ILog的)。当记录仪都解决了,我想按照他们正在解决的控制器它们被命名的。

事情是这样的:

  builder.Register(C => log4net.LogManager.GetLogger(NEED控制器名称HERE));
builder.Register(C =>新建Logging.Adapters.Log4NetAdapter(c.Resolve< log4net.ILog>()));
builder.RegisterType< Logging.Adapters.Log4NetAdapter>()为<&Logging.ILog GT;();
builder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());

任何想法,我怎么能有各自的WebAPI控制器根据控制器的类型名称收到个别记录器名称?

下面似乎工作,但似乎并不理想。

  builder.Register(C => log4net.LogManager.GetLogger(c.ComponentRegistry.Registrations.Last()Activator.LimitType.Name));
builder.Register(C =>新建Logging.Adapters.Log4NetAdapter(c.Resolve< log4net.ILog>()));
builder.RegisterType< Logging.Adapters.Log4NetAdapter>()为<&Logging.ILog GT;();
builder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());

我是新来autofac如此容忍我。结果
如果您发现上面我有一个附加层还是我自己的ILog和Log4NetAdapter /包装,以便有控制器和实际之间log4net的注册数层。

我需要的是这样的:

  APIController<  -  Logging.ILog<  -  Logging.Adapters.Log4NetAdapter<  -  log4net.ILog<  -  log4net.LogManager.GetLogger(APIController名)


解决方案

我用NLOG用的包装,但它肯定给可转换log4net的。这里是我的code:

 公共类日志:模块
{
    保护覆盖无效负载(ContainerBuilder建设者)
    {
        builder.Register((C,P)=> GetLogger(p.TypedAs<类型和GT;()));
    }    保护覆盖无效AttachToComponentRegistration(
        IComponentRegistry注册表,IComponentRegistration注册)
    {
        注册。preparing + =
            (发件人,参数)=>
            {
                VAR forType = args.Component.Activator.LimitType;                VAR logParameter =新ResolvedParameter(
                    (P,C)=> p.ParameterType == typeof运算(的ILog)
                    (P,C)=> c.ResolveLog(forType));                args.Parameters = args.Parameters.Union(新[] {logParameter});
            };
    }    公共静态的ILog GetLogger(类型类型)
    {
        返回新NLogLogger(类型);
    }
}公共静态类ResolveLogExtension
{
    公共静态的ILog ResolveLog< TService>(这IComponentContext上下文)
    {
        返回context.ResolveLog(typeof运算(TService));
    }    公共静态的ILog ResolveLog(这IComponentContext背景下,type类型)
    {
        返回context.Resolve&所述; ILog的>(TypedParameter.From(类型));
    }
}公共接口的ILog
{
    调试无效(字符串格式,params对象[]参数);
    无效信息(字符串格式,params对象[]参数);
    警告无效(字符串格式,params对象[]参数);    无效的错误(字符串格式,params对象[]参数);
    无效错误(异常前);
    无效错误(异常前,字符串格式,params对象[]参数);    无效致命(异常前,字符串格式,params对象[]参数);
}公共类NLogLogger:ILog的
{
    私人只读记录仪_log;    公共NLogLogger(类型类型)
    {
        _log = LogManager.GetLogger(type.FullName);
    }    公共无效调试(字符串格式,params对象[]参数)
    {
        _log.Debug(格式参数);
    }    公共无效信息(字符串格式,params对象[]参数)
    {
        _log.Info(格式参数);
    }    公共无效警告(字符串格式,params对象[]参数)
    {
        _log.Warn(格式参数);
    }    公共无效的错误(字符串格式,params对象[]参数)
    {
        _log.Error(格式参数);
    }    公共无效错误(异常前)
    {
        _log.ErrorException(,前);
    }    公共无效错误(异常前,字符串格式,params对象[]参数)
    {
        _log.ErrorException(的String.Format(格式参数),前);
    }    公共无效致命(异常前,字符串格式,params对象[]参数)
    {
        _log.FatalException(的String.Format(格式参数),前);
    }
}

I'm using autofac and trying to register WebApi controllers. Each controller takes a unique Logging.ILog as a constructor parameter (this is my ILog adapts to the log4net ILog). When loggers are resolved I would like them to be named according to the controller they are being resolved for.

Something like this:

builder.Register(c => log4net.LogManager.GetLogger("NEED CONTROLLER NAME HERE"));   
builder.Register(c => new Logging.Adapters.Log4NetAdapter(c.Resolve<log4net.ILog>()));
builder.RegisterType<Logging.Adapters.Log4NetAdapter>().As<Logging.ILog>();         
builder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());

Any idea how I can have each WebApi controller receive an individual logger name according to the controller type name?

The following seems to work but doesn't seem ideal.

builder.Register(c => log4net.LogManager.GetLogger(c.ComponentRegistry.Registrations.Last().Activator.LimitType.Name));
builder.Register(c => new Logging.Adapters.Log4NetAdapter(c.Resolve<log4net.ILog>()));
builder.RegisterType<Logging.Adapters.Log4NetAdapter>().As<Logging.ILog>();       
builder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());

I'm new to autofac so bear with me.
If you notice above I have an additional layer or my own ILog and Log4NetAdapter/Wrapper so that there are a few layer of registrations between the controller and the actual log4net.

I need something like:

APIController <- Logging.ILog <- Logging.Adapters.Log4NetAdapter <- log4net.ILog <- log4net.LogManager.GetLogger(APIController-Name)

解决方案

I use NLog with a wrapper, but it's certainly convertable to log4net. Here's my code:

public class LoggingModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.Register((c, p) => GetLogger(p.TypedAs<Type>()));
    }

    protected override void AttachToComponentRegistration(
        IComponentRegistry registry, IComponentRegistration registration)
    {
        registration.Preparing +=
            (sender, args) =>
            {
                var forType = args.Component.Activator.LimitType;

                var logParameter = new ResolvedParameter(
                    (p, c) => p.ParameterType == typeof (ILog),
                    (p, c) => c.ResolveLog(forType));

                args.Parameters = args.Parameters.Union(new[] {logParameter});
            };
    }

    public static ILog GetLogger(Type type)
    {
        return new NLogLogger(type);
    }
}

public static class ResolveLogExtension
{
    public static ILog ResolveLog<TService>(this IComponentContext context)
    {
        return context.ResolveLog(typeof (TService));
    }

    public static ILog ResolveLog(this IComponentContext context, Type type)
    {
        return context.Resolve<ILog>(TypedParameter.From(type));
    }
}

public interface ILog
{
    void Debug(string format, params object[] args);
    void Info(string format, params object[] args);
    void Warn(string format, params object[] args);

    void Error(string format, params object[] args);
    void Error(Exception ex);
    void Error(Exception ex, string format, params object[] args);

    void Fatal(Exception ex, string format, params object[] args);
}

public class NLogLogger : ILog
{
    private readonly Logger _log;

    public NLogLogger(Type type)
    {
        _log = LogManager.GetLogger(type.FullName);
    }

    public void Debug(string format, params object[] args)
    {
        _log.Debug(format, args);
    }

    public void Info(string format, params object[] args)
    {
        _log.Info(format, args);
    }

    public void Warn(string format, params object[] args)
    {
        _log.Warn(format, args);
    }

    public void Error(string format, params object[] args)
    {
        _log.Error(format, args);
    }

    public void Error(Exception ex)
    {
        _log.ErrorException("", ex);
    }

    public void Error(Exception ex, string format, params object[] args)
    {
        _log.ErrorException(string.Format(format, args), ex);
    }

    public void Fatal(Exception ex, string format, params object[] args)
    {
        _log.FatalException(string.Format(format, args), ex);
    }
}

这篇关于当使用autofac,我怎么使用的WebAPI控制器类型名称作为参数传递给depencency的注册?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆