forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dispose configuration providers (dotnet/extensions#861) (dotnet/exten…
…sions#928) - Dispose disposable configuration providers and their change token registrations when disposing the configuration root. - Dispose the change token registration when disposing a FileConfigurationProvider. Commit migrated from dotnet/extensions@95577f5
- Loading branch information
Showing
6 changed files
with
208 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
.../Microsoft.Extensions.Configuration.FileExtensions/tests/FileConfigurationProviderTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using Microsoft.Extensions.Configuration.Test; | ||
using Microsoft.Extensions.FileProviders; | ||
using Microsoft.Extensions.Primitives; | ||
using Moq; | ||
using Xunit; | ||
|
||
namespace Microsoft.Extensions.Configuration.FileExtensions.Test | ||
{ | ||
public class FileConfigurationProviderTest | ||
{ | ||
[Fact] | ||
public void ProviderDisposesChangeTokenRegistration() | ||
{ | ||
var changeToken = new ConfigurationRootTest.ChangeToken(); | ||
var fileProviderMock = new Mock<IFileProvider>(); | ||
fileProviderMock.Setup(fp => fp.Watch(It.IsAny<string>())).Returns(changeToken); | ||
|
||
var provider = new FileConfigurationProviderImpl(new FileConfigurationSourceImpl | ||
{ | ||
FileProvider = fileProviderMock.Object, | ||
ReloadOnChange = true, | ||
}); | ||
|
||
Assert.NotEmpty(changeToken.Callbacks); | ||
|
||
provider.Dispose(); | ||
|
||
Assert.Empty(changeToken.Callbacks); | ||
} | ||
|
||
public class FileConfigurationProviderImpl : FileConfigurationProvider | ||
{ | ||
public FileConfigurationProviderImpl(FileConfigurationSource source) | ||
: base(source) | ||
{ } | ||
|
||
public override void Load(Stream stream) | ||
{ } | ||
} | ||
|
||
public class FileConfigurationSourceImpl : FileConfigurationSource | ||
{ | ||
public override IConfigurationProvider Build(IConfigurationBuilder builder) | ||
{ | ||
EnsureDefaults(builder); | ||
return new FileConfigurationProviderImpl(this); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationRootTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Extensions.Primitives; | ||
using Moq; | ||
using Xunit; | ||
|
||
namespace Microsoft.Extensions.Configuration.Test | ||
{ | ||
public class ConfigurationRootTest | ||
{ | ||
[Fact] | ||
public void RootDisposesProviders() | ||
{ | ||
var provider1 = new TestConfigurationProvider("foo", "foo-value"); | ||
var provider2 = new DisposableTestConfigurationProvider("bar", "bar-value"); | ||
var provider3 = new TestConfigurationProvider("baz", "baz-value"); | ||
var provider4 = new DisposableTestConfigurationProvider("qux", "qux-value"); | ||
var provider5 = new DisposableTestConfigurationProvider("quux", "quux-value"); | ||
|
||
var config = new ConfigurationRoot(new IConfigurationProvider[] { | ||
provider1, provider2, provider3, provider4, provider5 | ||
}); | ||
|
||
Assert.Equal("foo-value", config["foo"]); | ||
Assert.Equal("bar-value", config["bar"]); | ||
Assert.Equal("baz-value", config["baz"]); | ||
Assert.Equal("qux-value", config["qux"]); | ||
Assert.Equal("quux-value", config["quux"]); | ||
|
||
config.Dispose(); | ||
|
||
Assert.True(provider2.IsDisposed); | ||
Assert.True(provider4.IsDisposed); | ||
Assert.True(provider5.IsDisposed); | ||
} | ||
|
||
[Fact] | ||
public void RootDisposesChangeTokenRegistrations() | ||
{ | ||
var changeToken = new ChangeToken(); | ||
var providerMock = new Mock<IConfigurationProvider>(); | ||
providerMock.Setup(p => p.GetReloadToken()).Returns(changeToken); | ||
|
||
var config = new ConfigurationRoot(new IConfigurationProvider[] { | ||
providerMock.Object, | ||
}); | ||
|
||
Assert.NotEmpty(changeToken.Callbacks); | ||
|
||
config.Dispose(); | ||
|
||
Assert.Empty(changeToken.Callbacks); | ||
} | ||
|
||
private class TestConfigurationProvider : ConfigurationProvider | ||
{ | ||
public TestConfigurationProvider(string key, string value) | ||
=> Data.Add(key, value); | ||
} | ||
|
||
private class DisposableTestConfigurationProvider : ConfigurationProvider, IDisposable | ||
{ | ||
public bool IsDisposed { get; set; } | ||
|
||
public DisposableTestConfigurationProvider(string key, string value) | ||
=> Data.Add(key, value); | ||
|
||
public void Dispose() | ||
=> IsDisposed = true; | ||
} | ||
|
||
public class ChangeToken : IChangeToken | ||
{ | ||
public List<(Action<object>, object)> Callbacks { get; } = new List<(Action<object>, object)>(); | ||
|
||
public bool HasChanged => false; | ||
|
||
public bool ActiveChangeCallbacks => true; | ||
|
||
public IDisposable RegisterChangeCallback(Action<object> callback, object state) | ||
{ | ||
var item = (callback, state); | ||
Callbacks.Add(item); | ||
return new DisposableAction(() => Callbacks.Remove(item)); | ||
} | ||
|
||
private class DisposableAction : IDisposable | ||
{ | ||
private Action _action; | ||
|
||
public DisposableAction(Action action) | ||
{ | ||
_action = action; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
var a = _action; | ||
if (a != null) | ||
{ | ||
_action = null; | ||
a(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |