C# 处理作用域方法

C# 处理作用域方法,c#,dispose,idisposable,asp.net-core-5.0,C#,Dispose,Idisposable,Asp.net Core 5.0,BinanceSpotClient实例化BinanceClient和BinanceSocketClient。必须在LiveTradeManager完成执行后处理它们。我在Dispose方法上放置了一个断点,但它当前未执行。我是否必须手动调用它,使LiveTradeManager继承IDisposable,然后调用BinanceSpotClient.Dispose services.addScope(); services.addScope(); services.addScope(); serv

BinanceSpotClient实例化
BinanceClient
BinanceSocketClient
。必须在LiveTradeManager完成执行后处理它们。我在Dispose方法上放置了一个断点,但它当前未执行。我是否必须手动调用它,使LiveTradeManager继承IDisposable,然后调用BinanceSpotClient.Dispose

services.addScope();
services.addScope();
services.addScope();
services.addScope();
公共接口ITradeManager { 任务RunAsync(); } 公共类LiveTradeManager:ITradeManager { 专用只读ILogger\u记录器; 专用只读IExchangeClient\u exchangeClient; 公共LiveTradeManager(ILogger记录器、IExchangeClientFactory和exchangeClientFactory) { _记录器=记录器; _exchangeClient=exchangeClientFactory.GetExchangeClient(exchangeOptions.Value.Exchange); } ... } 公共接口IExchangeClientFactory { IExchangeClient GetExchangeClient(Exchange); } 公共类ExchangeClientFactory:IExchangeClientFactory { 私有只读服务器ViceProvider\u服务提供商; public ExchangeClientFactory(IServiceProvider服务提供商) { _服务提供者=服务提供者; } 公共IExchangeClient GetExchangeClient(Exchange) { 返回交换开关 { Exchange.BinanceSpot=>ActivatorUtilities.CreateInstance(\u serviceProvider)??抛出新的NullReferenceException(), _=>抛出新ArgumentOutOfRangeException(nameof(exchange)、exchange、null) }; } } 公共类BinanceSpotClient:IExchangeClient,IDisposable { 专用只读ILogger\u记录器; 私有只读iBanceClient\u客户端; 私有只读iBananceCheckClient\u socketClient; 公共BinanceSpotClient(ILogger记录器、IOptions交换选项) { _记录器=记录器; _client=newbinanceclient(newbinanceclientoptions() { ApiCredentials=新的ApiCredentials(exchangeOptions.Value.ApiKey,exchangeOptions.Value.SecretKey), 自动时间戳=真, AutoTimestampRecalculationInterval=从分钟(30)开始的时间跨度, TradeRulesBehaviour=TradeRulesBehaviour.AutoComply }); _socketClient=new BinanceSocketClient(new BinanceSocketClientOptions() { ApiCredentials=新的ApiCredentials(exchangeOptions.Value.ApiKey,exchangeOptions.Value.SecretKey), AutoReconnect=true, ReconnectInterval=TimeSpan.FromSeconds(15) }); } private bool_disposed=false; 公共空间处置() { 处置(真实); 总干事(本); } 受保护的虚拟void Dispose(bool disposing) { 如果(_) 返回; 如果(处置) { 如果(_client!=null) { _client.Dispose(); } 如果(_socketClient!=null) { _socketClient.UnsubscribeAll(); _socketClient.Dispose(); } _subject.OnNext(Observable.Never()); } _这是真的; } } 我必须通过让LiveTradeManager继承来手动调用它吗 IDisposable,然后调用BinanceSpotClient.Dispose

如果您不想在容器中注册IExchangeClient,基本上可以

正在考虑向注册
IExchangeClient
。如果容器不知道,它就不能为您调用
Dispose
。这就意味着这是你的工作

显式工厂模式方法(您在这里使用)的一般问题正是您所经历的。这就是为什么我更喜欢Autofac的方法(/)-处理是容器的问题,因此您让容器成为工厂,以便它知道何时需要处理


要理解的关键是,使用当前代码,容器知道工厂的情况,但不知道工厂内部发生了什么您可以查看代码并看到需要处理的内容,但容器无法查看。如果实现了
IDisposable
,容器将处理工厂,但不是工厂正在创建的内容。

@mjwills,我有
服务。addScope()已在容器中注册。不要在服务范围中注册实例。然后,将不释放此方法创建的实例。更多信息:@Vernou,现在我明白了,伙计,非常感谢!如果需要,请键入答案。它使用
Exchange.BinanceSpot=>\u serviceProvider.GetService()调用Dispose方法??抛出新的NullReferenceException(),
感谢您的回答,是的,您是正确的。就像@Vernou在评论中说的那样。问题在于
ActivatorUtilities.CreateInstance()
没有将BinanceSpotClient注册到容器,而
\u serviceProvider.GetService()
使用
services.AddScoped()可以。这解决了问题。我目前不想使用Autofac,但感谢您的提议。是的,这正是我在评论和回答中所说的
正在考虑在容器中注册IExchangeClient。
。是的,非常感谢,@Vernou也感谢您。不过,要清楚,您可能不应该使用听起来像是您决定使用的解决方案。你应该完全删除<代码> Exchange Client Studio< /Cord>,直接注入客户机,而不是工厂。老实说,考虑查看一个更有能力的IOC容器。但工厂方法目前对你来说已经足够“有效”。很高兴听到你成功了!