Autofac:注册组件并根据解析父组件进行解析 [英] Autofac: Register component and resolve depending on resolving parent

查看:23
本文介绍了Autofac:注册组件并根据解析父组件进行解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想注册一个组件以根据它可能要解析的类使用参数进行解析.(这听起来有点令人困惑,所以我会举一个例子).

I'm wanting to register a component to resolve with parameters based on the class that it might be resolving for. (That sounds a bit confusing, so I'll show an example).

这是一个使用记录器的对象:

Here's an object that uses a logger:

class MyObject : IMyObject
{
    public ILogger Logger;
    public MyObject(ILogger logger)
    {
        Logger = logger;
    }
}

现在传入的记录器可能因类而异.因此,对于如何在下面执行此操作,我有一个相当完整的想法:

Now the logger that is passed in COULD be different from class to class. So I've got a rather patched idea for how to do that below:

class MyLogger : ILogger
{
    public string Name{get; protected set;}

    public static ILogger GetLogger(string className)
    {
        Name = className;
        MyLogger logger;
        // Do something to choose a logger for that specific class
        return logger;
    }
}

所以当我注册 Logger 时,我希望能够告诉它 className.我希望有一种方法可以做到与此类似:

So when I register Logger I want to be able to tell it the className. I'm hoping there's a way to do it similar to this:

ContainerBuilder builder = new ContainerBuilder();

builder.Register<MyLogger>(ctx =>
    {
        string className = //Get resolving class name somehow;
        return MyLogger.GetLogger(className);
    }).As<ILogger>();

builder.Register<MyObject>().As<IMyObject>();

var container = builder.Build();

IMyObject myObj = container.Resolve<IMyObject>();

//myObject.Logger.Name should now == "MyObject"

我想这样做的原因是为了避免在代码中使用带有 autofac 的记录器注册我实现的每个类.我希望能够在 xml 中注册所有对象,并且只需要一个 LoggerModule 来添加此注册.

The reason I want to do it this way is to avoid registering each class I implement with a logger with autofac in code. I want to be able to register all of the objects in xml, and simply have a LoggerModule, that adds this registration.

提前致谢!

推荐答案

这是我所做的(ILog 只是我自己的 log4net 包装器):

Here's what I do (ILog is just my own wrapper around log4net):

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.Resolve<ILog>(TypedParameter.From(forType)));

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

    public static ILog GetLogger(Type type)
    {
        return new Log4NetLogger(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 Log4NetLogger : ILog
{
    private readonly log4net.ILog _log;

    static Log4NetLogger()
    {
        XmlConfigurator.Configure();
    }

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

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

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

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

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

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

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

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

这篇关于Autofac:注册组件并根据解析父组件进行解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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