diff --git a/Aspects/Diagnostics/ExternalMetadata/WebExceptionDumpMetadata.cs b/Aspects/Diagnostics/ExternalMetadata/WebExceptionDumpMetadata.cs
index 5755e88..b8aa04a 100644
--- a/Aspects/Diagnostics/ExternalMetadata/WebExceptionDumpMetadata.cs
+++ b/Aspects/Diagnostics/ExternalMetadata/WebExceptionDumpMetadata.cs
@@ -1,4 +1,6 @@
using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
using System.IO;
using System.Net;
@@ -9,16 +11,19 @@ public abstract class WebExceptionDumpMetadata
{
///
[Dump(0)]
- public object Status;
+ public object Status { get; set; }
///
[Dump(1, DumpClass = typeof(WebExceptionDumpMetadata), DumpMethod = nameof(DumpResponse))]
- public object Response;
+ public object Response { get; set; }
///
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
public static string DumpResponse(
WebResponse response)
{
+ Contract.Ensures(Contract.Result() != null);
+
var stream = response?.GetResponseStream();
if (stream == null)
diff --git a/Aspects/Diagnostics/NuGet/PublishObjectDumper.cmd b/Aspects/Diagnostics/NuGet/PublishObjectDumper.cmd
index c526344..bdb823e 100644
--- a/Aspects/Diagnostics/NuGet/PublishObjectDumper.cmd
+++ b/Aspects/Diagnostics/NuGet/PublishObjectDumper.cmd
@@ -12,7 +12,7 @@ if not exist c:\NuGet md c:\NuGet
copy /y *.nupkg c:\NuGet
@echo Press any key to push to NuGet.org... > con:
@pause > nul:
-NuGet Push AspectObjectDumper.1.5.5.nupkg -source https://www.nuget.org/api/v2/
+NuGet Push AspectObjectDumper.1.5.5.nupkg -source https://www.nuget.org
:exit
popd
pause
\ No newline at end of file
diff --git a/Aspects/Linq/Expressions/Serialization/NuGet/ExpressionSerialization.nuspec b/Aspects/Linq/Expressions/Serialization/NuGet/ExpressionSerialization.nuspec
index b4b3c17..6eda703 100644
--- a/Aspects/Linq/Expressions/Serialization/NuGet/ExpressionSerialization.nuspec
+++ b/Aspects/Linq/Expressions/Serialization/NuGet/ExpressionSerialization.nuspec
@@ -2,7 +2,7 @@
AspectExpressionSerialization
- 1.0.50
+ 1.0.51
Val Melamed
Val Melamed
diff --git a/Aspects/Linq/Expressions/Serialization/Properties/AssemblyInfo.cs b/Aspects/Linq/Expressions/Serialization/Properties/AssemblyInfo.cs
index 033f0cf..135e2c3 100644
--- a/Aspects/Linq/Expressions/Serialization/Properties/AssemblyInfo.cs
+++ b/Aspects/Linq/Expressions/Serialization/Properties/AssemblyInfo.cs
@@ -4,9 +4,9 @@
[assembly: AssemblyTitle("vm.Aspects.Linq.Expressions.Serialization")]
[assembly: AssemblyDescription("Serializes and deserializes LINQ expression trees to and from XML documents.")]
-[assembly: AssemblyVersion("1.0.50")]
-[assembly: AssemblyFileVersion("1.0.50")]
-[assembly: AssemblyInformationalVersion("1.0.50")]
+[assembly: AssemblyVersion("1.0.51")]
+[assembly: AssemblyFileVersion("1.0.51")]
+[assembly: AssemblyInformationalVersion("1.0.51")]
[assembly: InternalsVisibleTo(
"vm.Aspects.Linq.Expressions.Serialization.Test, " +
diff --git a/Aspects/Model/EFRepository/EFRepositoryBase.cs b/Aspects/Model/EFRepository/EFRepositoryBase.cs
index baf96bc..cf4fbbd 100644
--- a/Aspects/Model/EFRepository/EFRepositoryBase.cs
+++ b/Aspects/Model/EFRepository/EFRepositoryBase.cs
@@ -320,6 +320,7 @@ IList ToValidationErrors(
/// is by this context or ownership was passed to this context when this context was created.
///
/// to release both managed and unmanaged resources; to release only unmanaged resources.
+ [SuppressMessage("Microsoft.Usage", "CA2215:Dispose methods should call base class dispose")]
protected override void Dispose(
bool disposing)
{
diff --git a/Aspects/Model/PerCallContextRepositoryCallHandler.cs b/Aspects/Model/PerCallContextRepositoryCallHandler.cs
index 86c523a..9bdc08c 100644
--- a/Aspects/Model/PerCallContextRepositoryCallHandler.cs
+++ b/Aspects/Model/PerCallContextRepositoryCallHandler.cs
@@ -72,6 +72,7 @@ public IMethodReturn Invoke(
#endregion
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The scope will be disposed in PostInvoke.")]
void PreInvoke(IMethodInvocation input)
{
if (!CreateTransactionScopeForTasks)
@@ -92,7 +93,7 @@ void PreInvoke(IMethodInvocation input)
input.InvocationContext["transactionScope"] = scope;
}
- IMethodReturn DoInvoke(
+ static IMethodReturn DoInvoke(
IMethodInvocation input,
GetNextHandlerDelegate getNext) => getNext().Invoke(input, getNext);
diff --git a/Aspects/Model/Properties/AssemblyInfo.cs b/Aspects/Model/Properties/AssemblyInfo.cs
index a3334e7..d6abf84 100644
--- a/Aspects/Model/Properties/AssemblyInfo.cs
+++ b/Aspects/Model/Properties/AssemblyInfo.cs
@@ -3,9 +3,9 @@
[assembly: AssemblyTitle("vm.Aspect.Model")]
[assembly: AssemblyDescription("Defines the IRepository and related base classes and utilities - a framework of building domain object model.")]
-[assembly: AssemblyVersion("1.0.50")]
-[assembly: AssemblyFileVersion("1.0.50")]
-[assembly: AssemblyInformationalVersion("1.0.50")]
+[assembly: AssemblyVersion("1.0.51")]
+[assembly: AssemblyFileVersion("1.0.51")]
+[assembly: AssemblyInformationalVersion("1.0.51")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(
"vm.Aspects.Model.Tests, " +
diff --git a/Aspects/NuGet/PublishAspects.cmd b/Aspects/NuGet/PublishAspects.cmd
index e7d7455..d290d32 100644
--- a/Aspects/NuGet/PublishAspects.cmd
+++ b/Aspects/NuGet/PublishAspects.cmd
@@ -19,7 +19,7 @@ if not exist c:\NuGet md c:\NuGet
copy /y *.nupkg c:\NuGet
@echo Press any key to push to NuGet.org... > con:
@pause > nul:
-NuGet Push vm.Aspects.1.0.50-beta.nupkg
+NuGet Push vm.Aspects.1.0.51-beta.nupkg -source https://www.nuget.org
:exit
popd
pause
\ No newline at end of file
diff --git a/Aspects/NuGet/vm.Aspects.nuspec b/Aspects/NuGet/vm.Aspects.nuspec
index 7fc25a5..49b5cb9 100644
--- a/Aspects/NuGet/vm.Aspects.nuspec
+++ b/Aspects/NuGet/vm.Aspects.nuspec
@@ -2,7 +2,7 @@
vm.Aspects
- 1.0.50-beta
+ 1.0.51-beta
Val Melamed
Val Melamed
diff --git a/Aspects/Parsers/Properties/AssemblyInfo.cs b/Aspects/Parsers/Properties/AssemblyInfo.cs
index 9db5a77..013ddeb 100644
--- a/Aspects/Parsers/Properties/AssemblyInfo.cs
+++ b/Aspects/Parsers/Properties/AssemblyInfo.cs
@@ -6,9 +6,9 @@
[assembly: AssemblyTitle("vm.Aspects.Parser")]
[assembly: AssemblyDescription("Text parsing readers, e.g. CSV/TSV reader.")]
-[assembly: AssemblyVersion("1.0.50")]
-[assembly: AssemblyFileVersion("1.0.50")]
-[assembly: AssemblyInformationalVersion("1.0.50")]
+[assembly: AssemblyVersion("1.0.51")]
+[assembly: AssemblyFileVersion("1.0.51")]
+[assembly: AssemblyInformationalVersion("1.0.51")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(
"vm.Aspects.Parsers.Tests, " +
diff --git a/Aspects/Properties/AssemblyInfo.cs b/Aspects/Properties/AssemblyInfo.cs
index 8a1fa91..651c220 100644
--- a/Aspects/Properties/AssemblyInfo.cs
+++ b/Aspects/Properties/AssemblyInfo.cs
@@ -2,9 +2,9 @@
[assembly: AssemblyTitle("vm.Aspects")]
[assembly: AssemblyDescription("A set of classes addressing various common cross-cutting concerns.")]
-[assembly: AssemblyVersion("1.0.50")]
-[assembly: AssemblyFileVersion("1.0.50")]
-[assembly: AssemblyInformationalVersion("1.0.50")]
+[assembly: AssemblyVersion("1.0.51")]
+[assembly: AssemblyFileVersion("1.0.51")]
+[assembly: AssemblyInformationalVersion("1.0.51")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(
"vm.Aspects.Test, " +
diff --git a/Aspects/Security/Cryptography/Ciphers/NuGet/PublishCiphers.cmd b/Aspects/Security/Cryptography/Ciphers/NuGet/PublishCiphers.cmd
index a81b136..4604823 100644
--- a/Aspects/Security/Cryptography/Ciphers/NuGet/PublishCiphers.cmd
+++ b/Aspects/Security/Cryptography/Ciphers/NuGet/PublishCiphers.cmd
@@ -18,7 +18,7 @@ if not exist c:\NuGet md c:\NuGet
copy /y *.nupkg c:\NuGet
@echo Press any key to push to NuGet.org... > con:
@pause > nul:
-NuGet Push Ciphers.1.11.9.nupkg -source https://www.nuget.org/api/v2/
+NuGet Push Ciphers.1.11.9.nupkg -source https://www.nuget.org
:exit
popd
pause
diff --git a/Aspects/Wcf/AsyncCallContext.cs b/Aspects/Wcf/AsyncCallContext.cs
index 016f086..13baf93 100644
--- a/Aspects/Wcf/AsyncCallContext.cs
+++ b/Aspects/Wcf/AsyncCallContext.cs
@@ -12,11 +12,16 @@ namespace vm.Aspects.Wcf
/// Maintains a simple synchronized key-value collection to replace
/// the one from the which is failing in asynchronous situations.
///
- public class AsyncCallContext
+ public class AsyncCallContext : IDisposable, IIsDisposed
{
readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
IDictionary _contextSlots = new Dictionary();
+ ///
+ /// Gets the current asynchronous call context.
+ ///
+ public static AsyncCallContext Current => CallContext.LogicalGetData(nameof(AsyncCallContext)) as AsyncCallContext;
+
///
/// Gets the entry at the data slot with name .
///
@@ -94,5 +99,68 @@ void ObjectInvariant()
{
Contract.Invariant(_contextSlots != null);
}
+
+ #region IDisposable pattern implementation
+ ///
+ /// The flag will be set just before the object is disposed.
+ ///
+ /// 0 - if the object is not disposed yet, any other value - the object is already disposed.
+ ///
+ /// Do not test or manipulate this flag outside of the property or the method .
+ /// The type of this field is Int32 so that it can be easily passed to the members of the class .
+ ///
+ int _disposed;
+
+ ///
+ /// Returns if the object has already been disposed, otherwise .
+ ///
+ public bool IsDisposed => Interlocked.CompareExchange(ref _disposed, 1, 1) == 1;
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ /// Invokes the protected virtual .
+ [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "It is correct.")]
+ public void Dispose()
+ {
+ // if it is disposed or in a process of disposing - return.
+ if (Interlocked.Exchange(ref _disposed, 1) != 0)
+ return;
+
+ // these will be called only if the instance is not disposed and is not in a process of disposing.
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Allows the object to attempt to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
+ ///
+ /// Invokes the protected virtual with parameter .
+ ~AsyncCallContext()
+ {
+ Dispose(false);
+ }
+
+ ///
+ /// Performs the actual job of disposing the object.
+ ///
+ ///
+ /// Passes the information whether this method is called by (explicitly or
+ /// implicitly at the end of a using statement), or by the finalizer.
+ ///
+ ///
+ /// If the method is called with ==, i.e. from ,
+ /// it will try to release all managed resources (usually aggregated objects which implement as well)
+ /// and then it will release all unmanaged resources if any. If the parameter is then
+ /// the method will only try to release the unmanaged resources.
+ ///
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposing)
+ return;
+
+ _lock.Dispose();
+ }
+ #endregion
}
}
diff --git a/Aspects/Wcf/Behaviors/AsyncCallContextMessageInspector.cs b/Aspects/Wcf/Behaviors/AsyncCallContextMessageInspector.cs
index 1044f6a..60a713a 100644
--- a/Aspects/Wcf/Behaviors/AsyncCallContextMessageInspector.cs
+++ b/Aspects/Wcf/Behaviors/AsyncCallContextMessageInspector.cs
@@ -1,6 +1,4 @@
-using System.Diagnostics;
-using System.Globalization;
-using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Messaging;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
@@ -29,9 +27,6 @@ public object AfterReceiveRequest(
CallContext.LogicalSetData(CallContextSlotName, context);
- Trace.WriteLine(
- string.Format(CultureInfo.InvariantCulture, "### Installed async context: {0}", context.GetHashCode().ToString()));
-
return null;
}
@@ -44,12 +39,10 @@ public void BeforeSendReply(
ref Message reply,
object correlationState)
{
- if (!ClearCallContext())
- Trace.WriteLine(
- string.Format(CultureInfo.InvariantCulture, "*** ASYNC CONTEXT WAS NOT FOUND!"));
+ ClearCallContext();
}
- bool ClearCallContext()
+ static bool ClearCallContext()
{
var context = CallContext.LogicalGetData(CallContextSlotName) as AsyncCallContext;
@@ -58,8 +51,6 @@ bool ClearCallContext()
context.Clear();
CallContext.FreeNamedDataSlot(CallContextSlotName);
- Trace.WriteLine(
- string.Format(CultureInfo.InvariantCulture, "### Cleared async context: {0}", context.GetHashCode().ToString()));
return true;
}
}
diff --git a/Aspects/Wcf/PerAsyncCallContextLifetimeManager.cs b/Aspects/Wcf/PerAsyncCallContextLifetimeManager.cs
index a88b8e5..d4a4b0b 100644
--- a/Aspects/Wcf/PerAsyncCallContextLifetimeManager.cs
+++ b/Aspects/Wcf/PerAsyncCallContextLifetimeManager.cs
@@ -40,7 +40,7 @@ public override void RemoveValue()
AsyncCallContext.FreeDataSlot(Key);
}
- AsyncCallContext AsyncCallContext
+ static AsyncCallContext AsyncCallContext
{
get
{
diff --git a/Aspects/Wcf/Properties/AssemblyInfo.cs b/Aspects/Wcf/Properties/AssemblyInfo.cs
index 390e4e3..fa0a57b 100644
--- a/Aspects/Wcf/Properties/AssemblyInfo.cs
+++ b/Aspects/Wcf/Properties/AssemblyInfo.cs
@@ -3,9 +3,9 @@
[assembly: AssemblyTitle("Wcf")]
[assembly: AssemblyDescription("A set of classes and generics simplifying the initial configuration work of creating WCF services.")]
-[assembly: AssemblyVersion("1.0.50")]
-[assembly: AssemblyFileVersion("1.0.50")]
-[assembly: AssemblyInformationalVersion("1.0.50")]
+[assembly: AssemblyVersion("1.0.51")]
+[assembly: AssemblyFileVersion("1.0.51")]
+[assembly: AssemblyInformationalVersion("1.0.51")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(
"vm.Aspects.Wcf.Test, " +