Harden disposal paths and test project metadata

This commit is contained in:
root
2026-02-23 21:31:07 +01:00
parent a2fd695738
commit 03b7d06a14
10 changed files with 192 additions and 122 deletions

View File

@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Description>Dynamic Object-Relational Mapping tests library.</Description> <Description>Dynamic Object-Relational Mapping tests library.</Description>
<Copyright>Copyright © RUSSEK Software 2012-2026</Copyright> <Copyright>Copyright © RUSSEK Software 2012-2026</Copyright>
<Company>RUSSEK Software</Company> <Company>RUSSEK Software</Company>
<Authors>Grzegorz Russek</Authors> <Authors>Grzegorz Russek</Authors>
@@ -11,10 +11,11 @@
<PackageProjectUrl>https://dr4cul4.pl</PackageProjectUrl> <PackageProjectUrl>https://dr4cul4.pl</PackageProjectUrl>
<Product>DynamORM</Product> <Product>DynamORM</Product>
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<ImplicitUsings>enable</ImplicitUsings> <IsTestProject>true</IsTestProject>
</PropertyGroup> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net4')) AND '$(MSBuildRuntimeType)' == 'Core' AND '$(OS)' != 'Windows_NT'"> <ItemGroup Condition="$(TargetFramework.StartsWith('net4')) AND '$(MSBuildRuntimeType)' == 'Core' AND '$(OS)' != 'Windows_NT'">
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="All" /> <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="All" />
@@ -41,4 +42,4 @@
<None Remove="Helpers\**" /> <None Remove="Helpers\**" />
<None Remove="Modify\**" /> <None Remove="Modify\**" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -960,14 +960,17 @@ namespace DynamORM.Builders.Implementation
/// <summary>Gets a value indicating whether this instance is disposed.</summary> /// <summary>Gets a value indicating whether this instance is disposed.</summary>
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
/// <summary>Performs application-defined tasks associated with /// <summary>Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.</summary> /// freeing, releasing, or resetting unmanaged resources.</summary>
public virtual void Dispose() public virtual void Dispose()
{ {
IsDisposed = true; if (IsDisposed)
return;
if (Database != null)
Database.RemoveFromCache(this); IsDisposed = true;
if (Database != null)
Database.RemoveFromCache(this);
if (Parameters != null) if (Parameters != null)
{ {
@@ -994,4 +997,4 @@ namespace DynamORM.Builders.Implementation
#endregion IExtendedDisposable #endregion IExtendedDisposable
} }
} }

View File

@@ -30,8 +30,9 @@ namespace DynamORM
internal IList<object> _cache; internal IList<object> _cache;
} }
private List<Data> _data = new List<Data>(); private List<Data> _data = new List<Data>();
private int _currentDataPosition = 0; private int _currentDataPosition = 0;
private bool _isDisposed;
private DynamicCachedReader() private DynamicCachedReader()
{ {
@@ -443,18 +444,34 @@ namespace DynamORM
/// <summary>Performs application-defined tasks associated with /// <summary>Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.</summary> /// freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose() public void Dispose()
{ {
foreach (var data in _data) if (_isDisposed)
{ return;
data._names.Clear();
data._types.Clear(); _isDisposed = true;
data._cache.Clear(); IsClosed = true;
data._schema.Dispose();
} if (_data == null)
return;
_data.Clear();
} foreach (var data in _data)
{
if (data == null)
continue;
if (data._names != null)
data._names.Clear();
if (data._types != null)
data._types.Clear();
if (data._cache != null)
data._cache.Clear();
if (data._schema != null)
data._schema.Dispose();
}
_data.Clear();
}
#endregion IDisposable Members #endregion IDisposable Members
@@ -721,4 +738,4 @@ namespace DynamORM
#endregion IDataRecord Members #endregion IDataRecord Members
} }
} }

View File

@@ -260,35 +260,51 @@ namespace DynamORM
#region IExtendedDisposable Members #region IExtendedDisposable Members
/// <summary>Performs application-defined tasks associated with /// <summary>Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.</summary> /// freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose() public void Dispose()
{ {
lock (_db.SyncLock) if (IsDisposed)
{ return;
if (_con != null)
{ var db = _db;
List<IDbCommand> pool = _db.CommandsPool.TryGetValue(_con.Connection); if (db == null)
{
if (pool != null && pool.Contains(this)) IsDisposed = true;
pool.Remove(this); return;
} }
IsDisposed = true; lock (db.SyncLock)
{
if (_command != null) if (IsDisposed)
{ return;
_command.Parameters.Clear();
IsDisposed = true;
_command.Dispose();
_command = null; if (_con != null)
} {
} List<IDbCommand> pool = db.CommandsPool.TryGetValue(_con.Connection);
}
if (pool != null && pool.Contains(this))
pool.Remove(this);
}
if (_command != null)
{
_command.Parameters.Clear();
_command.Dispose();
_command = null;
}
_con = null;
_db = null;
}
}
/// <summary>Gets a value indicating whether this instance is disposed.</summary> /// <summary>Gets a value indicating whether this instance is disposed.</summary>
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
#endregion IExtendedDisposable Members #endregion IExtendedDisposable Members
} }
} }

View File

@@ -161,17 +161,25 @@ namespace DynamORM
#region IExtendedDisposable Members #region IExtendedDisposable Members
/// <summary>Performs application-defined tasks associated with freeing, /// <summary>Performs application-defined tasks associated with freeing,
/// releasing, or resetting unmanaged resources.</summary> /// releasing, or resetting unmanaged resources.</summary>
public void Dispose() public void Dispose()
{ {
_db.Close(Connection); if (IsDisposed)
IsDisposed = true; return;
}
var db = _db;
if (db != null && Connection != null)
db.Close(Connection);
Connection = null;
_db = null;
IsDisposed = true;
}
/// <summary>Gets a value indicating whether this instance is disposed.</summary> /// <summary>Gets a value indicating whether this instance is disposed.</summary>
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
#endregion IExtendedDisposable Members #endregion IExtendedDisposable Members
} }
} }

View File

@@ -2006,13 +2006,16 @@ namespace DynamORM
#region IExtendedDisposable Members #region IExtendedDisposable Members
/// <summary>Performs application-defined tasks associated with freeing, /// <summary>Performs application-defined tasks associated with freeing,
/// releasing, or resetting unmanaged resources.</summary> /// releasing, or resetting unmanaged resources.</summary>
public void Dispose() public void Dispose()
{ {
#if !DYNAMORM_OMMIT_OLDSYNTAX if (IsDisposed)
List<DynamicTable> tables = TablesCache.Values.ToList(); return;
TablesCache.Clear();
#if !DYNAMORM_OMMIT_OLDSYNTAX
List<DynamicTable> tables = TablesCache.Values.ToList();
TablesCache.Clear();
tables.ForEach(t => t.Dispose()); tables.ForEach(t => t.Dispose());
tables.Clear(); tables.Clear();
@@ -2063,16 +2066,18 @@ namespace DynamORM
RemainingBuilders = null; RemainingBuilders = null;
} }
ClearSchema(); ClearSchema();
if (_proc != null) if (_proc != null)
_proc.Dispose(); _proc.Dispose();
IsDisposed = true; _proc = null;
} _tempConn = null;
IsDisposed = true;
}
/// <summary>Gets a value indicating whether this instance is disposed.</summary> /// <summary>Gets a value indicating whether this instance is disposed.</summary>
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
#endregion IExtendedDisposable Members #endregion IExtendedDisposable Members
} }
} }

View File

@@ -51,10 +51,11 @@ namespace DynamORM
/// public class ProcResult { [Column("outp")] public Guid Output { get; set; } } /// public class ProcResult { [Column("outp")] public Guid Output { get; set; } }
/// ProcResult res4 = db.Procedures.sp_Test_Scalar_In_Out&lt;ProcResult&gt;(inp: Guid.NewGuid(), out_outp: Guid.Empty) as ProcResult; /// ProcResult res4 = db.Procedures.sp_Test_Scalar_In_Out&lt;ProcResult&gt;(inp: Guid.NewGuid(), out_outp: Guid.Empty) as ProcResult;
/// </code>As you can se, you can use mapper to do job for you.</example> /// </code>As you can se, you can use mapper to do job for you.</example>
public class DynamicProcedureInvoker : DynamicObject, IDisposable public class DynamicProcedureInvoker : DynamicObject, IDisposable
{ {
private DynamicDatabase _db; private DynamicDatabase _db;
private List<string> _prefixes; private List<string> _prefixes;
private bool _isDisposed;
internal DynamicProcedureInvoker(DynamicDatabase db, List<string> prefixes = null) internal DynamicProcedureInvoker(DynamicDatabase db, List<string> prefixes = null)
{ {
@@ -446,10 +447,16 @@ namespace DynamORM
return true; return true;
} }
/// <summary>Performs application-defined tasks associated with /// <summary>Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.</summary> /// freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose() public void Dispose()
{ {
} if (_isDisposed)
} return;
}
_isDisposed = true;
_db = null;
_prefixes = null;
}
}
}

View File

@@ -950,15 +950,18 @@ namespace DynamORM
#region IExtendedDisposable Members #region IExtendedDisposable Members
/// <summary>Performs application-defined tasks associated with /// <summary>Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.</summary> /// freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose() public void Dispose()
{ {
// Lose reference but don't kill it. if (IsDisposed)
if (Database != null) return;
{
Database.RemoveFromCache(this); // Lose reference but don't kill it.
Database = null; if (Database != null)
{
Database.RemoveFromCache(this);
Database = null;
} }
IsDisposed = true; IsDisposed = true;
@@ -989,4 +992,4 @@ namespace DynamORM
} }
#endif #endif
} }

View File

@@ -170,20 +170,27 @@ namespace DynamORM
#region IExtendedDisposable Members #region IExtendedDisposable Members
/// <summary>Performs application-defined tasks associated with /// <summary>Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.</summary> /// freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose() public void Dispose()
{ {
_isDisposed = true; if (_isDisposed)
Rollback(); return;
if (_disposed != null) _isDisposed = true;
_disposed(); Rollback();
}
if (_disposed != null)
_disposed();
_disposed = null;
_con = null;
_db = null;
}
/// <summary>Gets a value indicating whether this instance is disposed.</summary> /// <summary>Gets a value indicating whether this instance is disposed.</summary>
public bool IsDisposed { get { return !_isOperational; } } public bool IsDisposed { get { return !_isOperational; } }
#endregion IExtendedDisposable Members #endregion IExtendedDisposable Members
} }
} }

View File

@@ -1444,15 +1444,18 @@ namespace DynamORM.Helpers.Dynamics
/// <summary>Gets a value indicating whether this instance is disposed.</summary> /// <summary>Gets a value indicating whether this instance is disposed.</summary>
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
/// <summary> /// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
IsDisposed = true; if (IsDisposed)
return;
if (_uncertainResult != null)
{ IsDisposed = true;
if (_uncertainResult != null)
{
if (_uncertainResult is Node) if (_uncertainResult is Node)
((Node)_uncertainResult).Dispose(); ((Node)_uncertainResult).Dispose();
@@ -1486,4 +1489,4 @@ namespace DynamORM.Helpers.Dynamics
#endregion Implementation of IExtendedDisposable #endregion Implementation of IExtendedDisposable
} }
} }