如何作为一个构造函数参数注入的依赖名称 [英] How to inject dependency name as a constructor parameter

查看:221
本文介绍了如何作为一个构造函数参数注入的依赖名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Autofac,我注册类使用属性注入,使用下面的code,以解决对接口:

Using Autofac, I can register a class to resolve against an interface using property injection, using the following code:

builder.RegisterType<Log4NetAdapter>()
       .As<ILogger>()
       .PropertiesAutowired()
       .InstancePerDependency();

不过,我的 Log4NetAdapter 类有需要调用类的名称的构造函数的参数。这样一来,我可以根据调用类的名称,记录事件。

However, my Log4NetAdapter class has a constructor parameter that requires the name of the calling class. This way, I can log events based upon the name of the calling class.

public class Log4NetAdapter : ILogger
{
    private readonly ILog _logger;

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

    ...
}

我怎么能注入的名称(即的typeof(依赖),请将.Name )的依赖成性注入类的构造函数因为每个依赖都会有自己的 Log4NetAdapter 实例?

How can I inject the name (i.e. typeof(dependency).Name) of the dependency into the property-injected class' constructor given that each dependency will have its own Log4NetAdapter instance?

推荐答案

更新:建筑上的 LogInjectionModule 样品和<一href="http://$c$c.google.com/p/autofac/source/browse/Core/Source/Autofac/Core/Activators/Reflection/AutowiringPropertyInjector.cs"相对=nofollow> Autofac如何做物业注入,我已经扩展模块,以做到既构造和财产注入。

Update: Building on the LogInjectionModule sample and how Autofac does property injection, I have extended the module to do both constructor and property injection.

注:我在 OnComponent preparing 固定传递给日志管理类型使用声明类型。这使得如解析&LT;函数功能:LT;服务&GT;&GT; 使用正确的日志类型。

Note: I've fixed the type passed to LogManager in OnComponentPreparing to use the declaring type. This makes e.g. Resolve<Func<Service>> use the correct log type.

    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);
            }
        }
    }

在如何使用该模块,这里有一个例子:

On how to use the module, here's a sample:

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>();

这篇关于如何作为一个构造函数参数注入的依赖名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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