从Unity中的自定义InjectionFactory获取当前构建对象

时间:2016-07-13 17:31:59

标签: c# dependency-injection unity-container ioc-container

是否可以使用自定义工厂方法在Unity中获取解析类型的父级。我正在尝试构建一个记录器,该记录器已经对其父对象应用了一些上下文。

// ... other types being registered
container.RegisterType<ILogger>(new InjectionFactory(ResolveLogger));

// Custom factory method
private ILogger ResolveLogger(IUnityContainer container)
{
    // I want to know the type of the parent that requires the ILogger interface so that I can add it to my logging context (with Serilog):
    Type parentType = ???
    return Log.Logger.ForContext(parentType);
}

当我创建一个类的实例时,Serilog允许我以这种方式为记录器设置上下文:

public class MyService
{
    private readonly ILogger logger;
    public MyService(ILogger logger)
    {
        this.logger = logger.ForContext(this.GetType());
    }
}

之后,对this.logger.Information("Hello World")的所有调用都将包含显示调用已在MyService类中完成的其他元数据。

我试图通过让Unity为我工作来避免记住在每个消耗记录器的课程中调用logger.ForContext(this.GetType())

1 个答案:

答案 0 :(得分:1)

我甚至认为自定义政策不会让你得到你想要的东西。我不确定是否有一个钩子可以让你看到“父”类型。我错了。但这是另一种解决方案和我使用的方法。

您可以使用泛型来获取调用类型(类似于您提到的public interface ILogger<T> { void Write(string message, [CallerMemberName] string callingMethod = ""); } ,但更优雅一点)。您可以使用[CallerMemberName]来获取调用成员的名称(方法名称,属性名称等)。

喜欢这个......

container.RegisterType(typeof(ILogger<>), typeof(ConsoleLogger<>));

Unity注册将使用这样的开放式泛型......

public class MyService
{
    public MyService(ILogger<MyFileService> logger)
    {
        // Check for nulls, set to member variable, etc.
    }
}

这是一个示例用法...

{{1}}

但请注意,这不适用于静态类型,因为静态类型不能用作泛型参数(这对我来说并不是一个问题,因为我试图避免使用静态类型)。

我已经嘲笑了一个例子here