我有一个连接提供程序类,它提供有关如何连接到服务的信息。提供程序根据可以在运行时更改的设置源隐藏内部连接信息提供程序的实现。我从工厂获得的实施。我这样做的原因是我不想在源更改时使用此类在其他类中创建新实例,并且他们只是在连接信息更改时收到通知,他们应该根据该事件采取行动。
像这样的东西:
public class ConnectionOptions
{
public Source Source { get; init; }
}
public interface IConnectionInfoProvider : IDisposable
{
event EventHandler? ConnectionInfoChanged;
public ConnectionInfo ConnectionInfo { get; }
}
public class ConnectionInfoProvider : IConnectionInfoProvider
{
public event EventHandler? ConnectionInfoChanged;
public ConnectionInfo ConnectionInfo => _connectionInfoProvider.ConnectionInfo;
private readonly Func<Source, Owned<IConnectionInfoProvider>> _connectionInfoFactory;
private IConnectionInfoProvider _connectionInfoProvider;
private readonly IDisposable _optionsChanged;
private ConnectionOptions _options;
public ConnectionInfoProvider(
Func<Source, Owned<IConnectionInfoProvider>> factory,
IOptionsMonitor<ConnectionOptions> optionsMonitor)
{
_connectionInfoFactory = factory;
_connectionInfoProvider = factory.Invoke(optionsMonitor.CurrentValue.Source);
_optionsChanged = optionsMonitor.OnChange(OnOptionsChanged);
}
private void OnOptionsChanged(ConnectionOptions options)
{
if (_options.Equals(options))
{
return;
}
// What is the best way to dispose here the old object with using Autofac?
_connectionInfoProvider?.Dispose(); // Just this?
_connectionInfoProvider = _connectionInfoFactory.Invoke(options.Source);
_connectionInfoProvider.ConnectionInfoChanged += ConnectionInfoChanged;
ConnectionInfoChanged?.Invoke(this, EventArgs.Empty);
}
// .... Dispose
}
例如用例的:
public class TcpClient
{
private readonly IConnectionInfoProvider _connectionInfoProvider;
public TcpClient(IConnectionInfoProvider connectionInfoProvider)
{
_connectionInfoProvider = connectionInfoProvider;
}
public void Start()
{
Connect();
_connectionInfoProvider.ConnectionInfoChanged += OnConnectionInfoChanged; // Reconnect the TcpClient
}
}
我想知道更改选项后处理对象的最佳方法是什么。最好手动执行,还是应该使用跟踪实例的 Autofac?我认为我想得太多了,让事情变得比事实更难。我有点困惑,尤其是对生命周期范围。如果我做对了并且我希望 Autofac 代替我来完成这项工作,我应该有类似的东西,对吧?:
private readonly ILifetimeScope _lifeTimeScope;
private ILifetimeScope? _usedScope;
public ConnectionInfoProvider(
IOptionsMonitor<ConnectionOptions> optionsMonitor,
ILifetimeScope lifetimeScope)
{
_lifeTimeScope = lifetimeScope;
_options = optionsMonitor.CurrentValue;
_optionsChanged = optionsMonitor.OnChange(OnOptionsChanged);
SetConnectionProvider();
}
private void SetConnectionProvider()
{
_usedScope?.Dispose();
_usedScope = _lifeTimeScope.BeginLifetimeScope();
_connectionInfoProvider = _usedScope.Resolve<Func<Source, IConnectionInfoProvider>>().Invoke(_options.Source);
_connectionInfoProvider.ConnectionInfoChanged += ConnectionInfoChanged;
}
private void OnOptionsChanged(ConnectionOptions options)
{
if (_options.Equals(options))
{
return;
}
SetConnectionProvider();
ConnectionInfoChanged?.Invoke(this, EventArgs.Empty);
}
// .... Dispose
在 Autofac 中,我会在每次解析时使用 InstancePerLifetimeScope 或新实例。但这在我看来有点奇怪,太复杂了,而且在我自己控制对象生命周期的第一种情况下看起来更好。特别是我还没有看到任何使用生命周期范围的例子,就像我展示的那样。 99% 的人使用关键字而不是私人会员来使用它。但也许还有另一种方法可以做得更好。