gpt4 book ai didi

c# - 如何将依赖项名称作为构造函数参数注入(inject)

转载 作者:太空狗 更新时间:2023-10-29 23:16:09 27 4
gpt4 key购买 nike

使用 Autofac,我可以注册一个类来解析使用属性注入(inject)的接口(interface),使用以下代码:

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

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

public class Log4NetAdapter : ILogger
{
private readonly ILog _logger;

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

...
}

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

最佳答案

更新:建立在LogInjectionModule sample 和 how Autofac does property injection ,我扩展了模块以执行构造函数和属性注入(inject)。

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

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

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

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

关于c# - 如何将依赖项名称作为构造函数参数注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14484243/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com