using System;
using System.IO;
using System.Threading;
namespace Microsoft.AspNetCore.NodeServices
{
///
/// Makes it easier to pass script files to Node in a way that's sure to clean up after the process exits.
///
public sealed class StringAsTempFile : IDisposable
{
private bool _disposedValue;
private bool _hasDeletedTempFile;
private object _fileDeletionLock = new object();
private IDisposable _applicationLifetimeRegistration;
///
/// Create a new instance of .
///
/// The contents of the temporary file to be created.
/// A token that indicates when the host application is stopping.
public StringAsTempFile(string content, CancellationToken applicationStoppingToken)
{
FileName = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
File.WriteAllText(FileName, content);
// Because .NET finalizers don't reliably run when the process is terminating, also
// add event handlers for other shutdown scenarios.
_applicationLifetimeRegistration = applicationStoppingToken.Register(EnsureTempFileDeleted);
}
///
/// Specifies the filename of the temporary file.
///
public string FileName { get; }
///
/// Disposes the instance and deletes the associated temporary file.
///
public void Dispose()
{
DisposeImpl(true);
GC.SuppressFinalize(this);
}
private void DisposeImpl(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
// Dispose managed state
_applicationLifetimeRegistration.Dispose();
}
EnsureTempFileDeleted();
_disposedValue = true;
}
}
private void EnsureTempFileDeleted()
{
lock (_fileDeletionLock)
{
if (!_hasDeletedTempFile)
{
File.Delete(FileName);
_hasDeletedTempFile = true;
}
}
}
///
/// Implements the finalization part of the IDisposable pattern by calling Dispose(false).
///
~StringAsTempFile()
{
DisposeImpl(false);
}
}
}