我想使用AddScoped方法在ServiceCollection中注册TelemetryClient,并在处置客户端时调用Flush
。在作用域完成显式调用后,我无权访问TelemetryClient
,并且我需要将TelemetryClient
传递给第三方方法的方法,因此我不能使用包装器。
我在Azure Functions中使用.Net Core的内置Di容器。
我正在这样注册它:
services.AddScoped(x =>
{
return new TelemetryClient();
});
我想在Autofac中使用类似OnRelease的方法,因此我可以像下面这样注册它。请注意对OnRelease
的调用:
services.AddScoped(x =>
{
return new TelemetryClient();
}).OnRelease(x=>
{
x.Flush();
});
答案 0 :(得分:1)
您可以像这样包装TelemetryClient
:
public interface ILogsStuff
{
void LogSomething(string message);
}
public class TelemetryClientLogger : ILogsStuff, IDisposable
{
private readonly TelemetryClient _telemetryClient;
public TelemetryClientLogger(TelemetryClient telemetryClient)
{
_telemetryClient = telemetryClient;
}
public void LogSomething(string message)
{
_telemetryClient.TrackTrace(message);
}
public void Dispose()
{
_telemetryClient.Flush();
}
}
还有一个额外的好处,那就是,无论您将其注入哪个类,都不会直接依赖于TelemetryClient
。您可以定义一个接口,该接口描述要使用客户端的任何对象,并且如果需要,可以更轻松地模拟和替换为其他实现。
suggestion was made使TelemetryClient
实现IDisposable
并在处置时使其调用Flush()
,这是推荐的解决方案。
问题的更新内容如下:
我需要将TelemetryClient传递给第三方方法,这样我才能使用包装器。
这会有所改变,因为现在的目的不是使用 TelemetryClient
,而是解决它,然后将其传递给第三方库的方法。之所以如此,是因为它意味着该库强制使用它的代码对TelemetryClient
具有严格的依赖性,并且可能无法按预期方式处理该客户端。
这时仍然有解决方案,但是它们都是丑陋的,因为它们是解决不应该存在的怪异问题的解决方案(不是由您的代码创建的)。
如果要将TelemetryClient
传递给方法,该方法将写入该方法,然后必须对其进行刷新,为什么那个库不刷新它?
您可以通过在执行过程中将TelemetryClient
传递给方法,然后在方法执行后刷新客户端来解决该问题。
CallSomeMethod(someArgument, _telemtryClient);
telemetryClient.Flush();
或者,为了使结果更接近您的问题,您可以这样做,虽然可以获得结果,但是仍然很尴尬和奇怪:
public class TelemetryClientWrapper : IDisposable
{
private readonly TelemetryClient _telemetryClient;
public TelemetryClientWrapper(TelemetryClient telemetryClient)
{
_telemetryClient = telemetryClient;
}
public TelemetryClient Client => _telemetryClient;
public void Dispose()
{
_telemetryClient.Flush();
}
}
您可以注入此类并将其传递给库的方法,如下所示:
CallSomeMethod(someArgument, _telemtryClientWrapper.Client);
现在的问题是,即使不使用它,您的类也对TelemetryClient
有严格的依赖关系,所有这些都可以修复其他库(大概是)。不能正确处理该客户。
说了这么多,也许是在您的场景this is the answer中:
内置服务容器旨在满足框架和大多数消费者应用程序的需求。我们建议您使用内置容器,除非您需要它不支持的特定功能。内置容器中找不到第三方容器支持的一些功能:
换句话说,如果您需要Autofac的功能,则可以将still use Autofac与IServiceCollection
一起使用。