在 DryIoc 容器中注册 ILoggerFactory

Ale*_*ego 5 logging prism xamarin.forms dryioc

我想将 Microsoft.Extensions.Logging 与 DryIoc 容器一起使用。

默认方式是将工厂注册为实例,注入它并创建一个记录器:

ILoggerFactory loggerFactory = new LoggerFactory().AddDebug();
container.RegisterInstance(loggerFactory);

// inject factory in constructor
public MyService(ILoggerFactory loggerFactory){
 this.logger = loggerFactory.CreateLogger<MyService>()

 this.logger.LogInformation("Logger created");
}
Run Code Online (Sandbox Code Playgroud)

但我想要一个更像 ASP.NET Core 的行为,直接注入 Logger:

// inject logger in constructor
public MyService(ILogger<MyService> logger){
 this.logger = logger;

 this.logger.LogInformation("Logger created");
}
Run Code Online (Sandbox Code Playgroud)

因此,由于某些配置,我需要创建 ILoggerFactory 的实例,并且必须在请求时使用“CreateLogger”方法在容器中注册 ILogger<> 接口。

我尝试使用来自https://bitbucket.org/dadhi/dryioc/wiki/SelectConstructorOrFactoryMethod的工厂方法注册,但没有成功。

最终得到了这样的结果,但缺少 CreateLogger<> 中的泛型:

container.Register(typeof(ILogger<>), made: Made.Of(() => loggerFactory.CreateLogger<>()));
Run Code Online (Sandbox Code Playgroud)

也许任何人都可以提供帮助。

编辑

您必须这样做才能获得正确的工厂方法:

var loggerFactoryMethod = typeof(LoggerFactoryExtensions).GetMethod("CreateLogger", new Type[] { typeof(ILoggerFactory) });
Run Code Online (Sandbox Code Playgroud)

我创建和更新,在此使用Xamarin.Forms的工作示例(与棱镜和DryIoc)github.com/dernippel/PrismNetCoreLoggingApp

dad*_*dhi 5

这是基于示例接口和类的完整工作示例。
实时播放代码就在这里

using System;
using DryIoc;

public class Program
{
    public static void Main()
    {   
        var container = new Container();

        // note usage of UseInstance instead of obsolete RegisterInstance
        container.UseInstance(new LoggerFactory()); 

        var loggerFactoryMethod = typeof(LoggerFactory).GetMethod("CreateLogger");

        container.Register(typeof(ILogger<>), made: Made.Of(
            req => loggerFactoryMethod.MakeGenericMethod(req.Parent.ImplementationType),
            ServiceInfo.Of<LoggerFactory>()));

        container.Register<MyService>();

        container.Resolve<MyService>();
    }

    class MyService 
    {   
        public MyService(ILogger<MyService> logger) { logger.Log("Hey!"); }
    }

    interface ILogger<T> 
    {
        void Log(string msg);
    }

    class ConsoleLogger<T> : ILogger<T>
    {
        public void Log(string msg) { Console.WriteLine(typeof(T) + ": " + msg); }
    }

    class LoggerFactory 
    {
        public ILogger<T> CreateLogger<T>() { return new ConsoleLogger<T>(); }
    }
}
Run Code Online (Sandbox Code Playgroud)

静态 LoggerFactoryExtensions 的更新

对于静态方法,设置更简单,您不需要通过指定工厂实例ServiceInfo.Of<LoggerFactory>(),它将作为任何其他参数注入。

以下是更改(实时示例已更新):

    var loggerFactoryMethod = typeof(LoggerFactoryExtensions).GetMethod("CreateLogger");

    container.Register(typeof(ILogger<>), made: Made.Of(
        req => loggerFactoryMethod.MakeGenericMethod(req.Parent.ImplementationType)));
Run Code Online (Sandbox Code Playgroud)

鉴于扩展:

public static class LoggerFactoryExtensions
{
    public static ILogger<T> CreateLogger<T>(this LoggerFactory f) { return new ConsoleLogger<T>(); }
}
Run Code Online (Sandbox Code Playgroud)