在DryIoc容器

时间:2018-02-21 17:11:58

标签: logging xamarin.forms prism 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");
}

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

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

 this.logger.LogInformation("Logger created");
}

因此,我需要根据某些配置创建ILoggerFactory的实例,并且ILogger&lt;&gt;必要时,必须使用“CreateLogger”方法在容器中注册接口。

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

结束了类似的事情,但CreateLogger&lt;&gt;中的泛型缺少:

container.Register(typeof(ILogger<>), made: Made.Of(() => loggerFactory.CreateLogger<>()));

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

修改

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

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

我使用Xamarin.Forms(使用Prism和DryIoc)在github.com/dernippel/PrismNetCoreLoggingApp

创建并更新了这个样本的工作样本

1 个答案:

答案 0 :(得分:1)

以下是基于示例接口和类的完整工作示例 要播放的实时代码为here

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

静态LoggerFactoryExtensions的更新

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

以下是更改(live sample is updated):

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

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

鉴于扩展名:

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