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

本文关键字:构建 对象 获取 InjectionFactory Unity 自定义 | 更新日期: 2023-09-27 17:57:00

是否可以

使用自定义工厂方法在 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())

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

我什至不认为自定义策略会让您获得您所追求的东西。 我不确定是否有一个钩子可以让您了解"父"类型。 我可能是错的。 但这里有一个替代解决方案和我使用的东西。

您可以使用泛型来获取调用类型(类似于您提到的ForContext,但更优雅一些)。 您可以使用[CallerMemberName]来获取调用成员的名称(方法名称、属性名称等)。


喜欢这个。。。

public interface ILogger<T>
{
    void Write(string message, [CallerMemberName] string callingMethod = "");
}

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

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

下面是一个用法示例...

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

但请注意,这不适用于静态类型,

因为静态类型不能用作泛型参数(这对我来说不是什么大问题,因为我尽量避免静态类型)。

我在这里模拟了一个例子。