gpt4 book ai didi

c# - Autofac 通用接口(interface)工厂

转载 作者:行者123 更新时间:2023-11-30 23:13:10 26 4
gpt4 key购买 nike

我有一个 ILoggerFactory 在 Autofac 容器中注册的实现。我希望能够使用 Autofac 注册以下类并能够实例化它:

public class Test
{
public Test(ILogger<Test> logger)
{
logger.LogInformation("Works!");
}
}

为此,我需要能够“教”Autofac 生成实现 ILogger<T> 的实例对于任何类(class) T .有一个 ILoggerFactory扩展方法 CreateLogger<T>() CreateLogger(Type) 能够生成所需类型的实例,但我不知道如何让 Autofac 调用它们。

如果我想要非泛型 ILogger , 我会写

containerBuilder.Register(c => c.Resolve<ILoggerFactory>().CreateLogger("default"))

但我不确定如何处理通用的。有什么指点吗?

更新:阅读更多内容后documentation ,我想到了这个:

public class LoggingModule: Autofac.Module
{
private readonly MethodInfo mi;

public LoggingModule()
{
this.mi = typeof(LoggerFactoryExtensions)
.GetMethod(nameof(LoggerFactoryExtensions.CreateLogger), new[] { typeof(ILoggerFactory) });
}

protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
registration.Preparing += OnComponentPreparing;
}

private void OnComponentPreparing(object sender, PreparingEventArgs e)
{
e.Parameters = e.Parameters.Union(
new[]
{
new ResolvedParameter(
(p, i) => IsGenericLoggerParameter(p.ParameterType),
(p, i) => CreateLogger(this.mi, p.ParameterType, i.Resolve<ILoggerFactory>())
)
});
}

private static bool IsGenericLoggerParameter(Type parameterType)
{
return parameterType.IsGenericType && parameterType.GetGenericTypeDefinition() == typeof(ILogger<>);
}

private static object CreateLogger(MethodInfo mi, Type typeArg, ILoggerFactory loggerFactory)
{
Type genericArg = typeArg.GetGenericArguments().First();
MethodInfo generic = mi.MakeGenericMethod(new[] { genericArg });
return generic.Invoke(null, new[] { loggerFactory });
}
}

然后:

        containerBuilder.RegisterType<Test>().AsSelf();
containerBuilder.RegisterModule<LoggingModule>();
var container = containerBuilder.Build();
var test = container.Resolve<Test>();

有效。问题是我不完全理解它是如何工作的(更重要的是,它可能会如何崩溃),所以我仍在寻找更优雅和/或更易于理解的解决方案。

最佳答案

我找到了一个简单的答案,但只针对 ILogger<T>来自 Microsoft.Extensions.Logging包装:使用 ServiceCollection来自 Microsoft.Extensions.DependencyInjection包裹:

        IServiceCollection services = new ServiceCollection();
services.AddLogging(); // all the magic happens here
// set up other services
var builder = new ContainerBuilder();
builder.Populate(services); // from the Autofac.Extensions.DependencyInjection package
IContainer container = builder.Build();
Test t = container.Resolve<Test>();

关于c# - Autofac 通用接口(interface)工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43750179/

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