从 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())
。
我什至不认为自定义策略会让您获得您所追求的东西。 我不确定是否有一个钩子可以让您了解"父"类型。 我可能是错的。 但这里有一个替代解决方案和我使用的东西。
您可以使用泛型来获取调用类型(类似于您提到的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.
}
}
但请注意,这不适用于静态类型,
因为静态类型不能用作泛型参数(这对我来说不是什么大问题,因为我尽量避免静态类型)。
我在这里模拟了一个例子。