首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将依赖项名称作为构造函数参数注入

如何将依赖项名称作为构造函数参数注入
EN

Stack Overflow用户
提问于 2013-01-24 00:17:17
回答 2查看 1.6K关注 0票数 5

使用Autofac,我可以使用以下代码注册一个类,并使用属性注入对接口进行解析:

代码语言:javascript
复制
builder.RegisterType<Log4NetAdapter>()
       .As<ILogger>()
       .PropertiesAutowired()
       .InstancePerDependency();

但是,我的Log4NetAdapter类有一个构造函数参数,它需要调用类的名称。这样,我就可以根据调用类的名称记录事件。

代码语言:javascript
复制
public class Log4NetAdapter : ILogger
{
    private readonly ILog _logger;

    public Log4NetAdapter(string logName)
    {
        _logger = LogManager.GetLogger(logName);
    }

    ...
}

假设每个依赖项都有自己的Log4NetAdapter实例,我如何将依赖项的名称(即typeof(dependency).Name)注入到属性注入类的构造函数中?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-24 00:52:12

更新:LogInjectionModule示例和how Autofac does property injection的基础上,我扩展了该模块以执行构造函数和属性注入。

注意:我已经修复了在OnComponentPreparing中传递给LogManager的类型,以便使用声明类型。这使得例如Resolve<Func<Service>>使用正确的日志类型。

代码语言:javascript
复制
    using System.Linq;
    using log4net;

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

        private static void OnComponentActivating(object sender, ActivatingEventArgs<object> e)
        {
            InjectLogProperties(e.Context, e.Instance, false);
        }

        private static void OnComponentPreparing(object sender, PreparingEventArgs e)
        {
            e.Parameters = e.Parameters.Union(new[]
                {
                    new ResolvedParameter(
                       (p, i) => p.ParameterType == typeof(ILog),
                       (p, i) => LogManager.GetLogger(p.Member.DeclaringType))
                });
        }

        private static void InjectLogProperties(IComponentContext context, object instance, bool overrideSetValues)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (instance == null) throw new ArgumentNullException("instance");

            var instanceType = instance.GetType();
            var properties = instanceType
                .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .Where(pi => pi.CanWrite && pi.PropertyType == typeof(ILog));

            foreach (var property in properties)
            {
                if (property.GetIndexParameters().Length != 0)
                    continue;

                var accessors = property.GetAccessors(false);
                if (accessors.Length == 1 && accessors[0].ReturnType != typeof(void))
                    continue;

                if (!overrideSetValues &&
                    accessors.Length == 2 &&
                    (property.GetValue(instance, null) != null))
                    continue;

                ILog propertyValue = LogManager.GetLogger(instanceType);
                property.SetValue(instance, propertyValue, null);
            }
        }
    }

关于如何使用该模块,这里有一个示例:

代码语言:javascript
复制
public class Service
{
    public Service(ILog log) { ... }
}

var cb = new ContainerBuilder();
cb.RegisterModule<LogInjectionModule>();
cb.RegisterType<Service>();
var c = cb.Build();

var service = c.Resolve<Service>();
票数 4
EN

Stack Overflow用户

发布于 2013-01-24 00:46:27

您只能使用logName按名称有效地解析ILog,那么为什么不直接注入ILog

代码语言:javascript
复制
public class Log4NetAdapter : ILogger
{
    private readonly ILog _logger;

    public Log4NetAdapter(ILog logger)
    {
        _logger = logger;
    }

    ...
}

好了,现在我只是稍微转移了一下问题,但我也减少了与其他类的耦合,即LogManager

因此,如果我使用unity,那么我会这样做,以确保获得正确的记录器:

代码语言:javascript
复制
var childContainer = container.CreateChildContainer();
childContainer.RegisterInstance<ILog>(LogManager.GetLogger(logName));
var adaptor = childContainer.Resolve<Log4NetAdapter>();

子容器阻止任何其他代码访问该ILog。你想怎么做就怎么做,我对你的代码一无所知。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14484243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档