/// <summary> /// Releases all resources consumed by the current <see cref="ReferenceManager" />. /// </summary> /// <param name="disposing"> /// A value indicating whether or not managed resources should be released. /// </param> protected override void Dispose(Boolean disposing) { try { if (disposing) { var disposedReferences = new List <IDisposable>(); while (References.Count > 0) { IDisposable reference; using (var controlToken = StateControl.Enter()) { reference = References.Dequeue(); } reference.Dispose(); } } } finally { base.Dispose(disposing); } }
/// <summary> /// Gets a shared, managed <see cref="ISenderClient" /> instance that is used to submit request messages. /// </summary> /// <typeparam name="TRequestMessage"> /// The type of the request message. /// </typeparam> /// <typeparam name="TResponseMessage"> /// The type of the response message. /// </typeparam> /// <returns> /// The managed <see cref="ISenderClient" /> instance. /// </returns> /// <exception cref="MessagePublishingException"> /// An exception was raised while creating the send client. /// </exception> /// <exception cref="MessageSubscriptionException"> /// An exception was raised while creating the receive client. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public ISenderClient GetRequestClient <TRequestMessage, TResponseMessage>() where TRequestMessage : class, IRequestMessage <TResponseMessage> where TResponseMessage : class, IResponseMessage { var requestMessageEntityType = MessagePublishingClient.RequestMessageEntityType; var responseMessageEntityType = MessageSubscriptionClient.ResponseMessageEntityType; var responseMessageEntityPath = GetEntityPath <TResponseMessage>(responseMessageEntityType); var requestMessageSendClient = GetSendClient <TRequestMessage>(requestMessageEntityType); using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (SendClientDictionary.ContainsKey(responseMessageEntityPath) == false) { var responseMessageSendClient = ClientFactory.CreateSendClient <TResponseMessage>(responseMessageEntityType); SendClientDictionary.Add(responseMessageEntityPath, responseMessageSendClient); } if (ReceiveClientDictionary.ContainsKey(responseMessageEntityPath) == false) { var responseMessageReceiveClient = ClientFactory.CreateReceiveClient <TResponseMessage>(responseMessageEntityType); responseMessageReceiveClient.RegisterMessageHandler(HandleResponseMessage, ReceiverOptionsForResponseMessages); ReceiveClientDictionary.Add(responseMessageEntityPath, responseMessageReceiveClient); } } return(requestMessageSendClient); }
/// <summary> /// Processes the specified <see cref="ICommand{TResult}" />. /// </summary> /// <typeparam name="TResult"> /// The type of the result that is produced by processing the command. /// </typeparam> /// <param name="command"> /// The command to process. /// </param> /// <returns> /// The result that is produced by processing the command. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="command" /> is <see langword="null" />. /// </exception> /// <exception cref="CommandHandlingException"> /// An exception was raised while processing the command. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public TResult Process <TResult>(ICommand <TResult> command) { var commandType = command.RejectIf().IsNull(nameof(command)).TargetArgument.GetType(); try { var registeredHandlerType = CommandHandlerRegisteredType.MakeGenericType(commandType); var implementedHandlerType = CommandHandlerImplementedType.MakeGenericType(commandType, typeof(TResult)); var processMethod = implementedHandlerType.GetMethod(CommandHandlerProcessMethodName); var processMethodArguments = new Object[1] { command }; using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); var commandHandler = Scope.Resolve(registeredHandlerType); var result = processMethod.Invoke(commandHandler, processMethodArguments); return((TResult)result); } } catch (CommandHandlingException) { throw; } catch (ObjectDisposedException) { throw; } catch (Exception exception) { throw new CommandHandlingException(commandType, exception); } }
/// <summary> /// Releases all resources consumed by the current <see cref="DependencyContainer{TContainer, TConfigurator}" />. /// </summary> /// <param name="disposing"> /// A value indicating whether or not managed resources should be released. /// </param> protected override void Dispose(Boolean disposing) { try { if (disposing) { using (var controlToken = StateControl.Enter()) { try { LazySourceContainer.Dispose(); LazyRootScope.Dispose(); } finally { LazyReferenceManager.Dispose(); } } } } finally { base.Dispose(disposing); } }
internal void DestroySubscription(String topicPath, String subscriptionName) { using (var controlToken = StateControl.Enter()) { controlToken.AttachTask(DestroySubscriptionAsync(topicPath.RejectIf().IsNullOrEmpty(nameof(topicPath)), subscriptionName.RejectIf().IsNullOrEmpty(nameof(subscriptionName)))); } }
/// <summary> /// Changes the channel's status to <see cref="ChannelStatus.Live" /> if it is currently silent, otherwise changes the status /// to <see cref="ChannelStatus.Silent" /> if it is currently live, otherwise raises an /// <see cref="InvalidOperationException" />. /// </summary> /// <exception cref="InvalidOperationException"> /// The channel's status is equal to <see cref="ChannelStatus.Unavailable" />. /// </exception> public void Toggle() { using (var controlToken = StateControl.Enter()) { switch (Status) { case ChannelStatus.Live: Status = ChannelStatus.Silent; break; case ChannelStatus.Silent: Status = ChannelStatus.Live; break; case ChannelStatus.Unavailable: throw new InvalidOperationException("The channel is unavailable."); default: throw new InvalidOperationException($"The specified channel status, {Status}, is not supported."); } } }
/// <summary> /// Determines whether or not the specified entity exists in the current <see cref="DataAccessRepository{TEntity}" />. /// </summary> /// <param name="entity"> /// The entity to evaluate. /// </param> /// <returns> /// <see langword="true" /> if the specified entity exists in the current <see cref="DataAccessRepository{TEntity}" />, /// otherwise <see langword="false" />. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="entity" /> is <see langword="null" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public Boolean Contains(TEntity entity) { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); return(Contains(entity.RejectIf().IsNull(nameof(entity)), controlToken)); } }
/// <summary> /// Returns all entities matching the specified predicate from the current <see cref="DataAccessRepository{TEntity}" />. /// </summary> /// <param name="predicate"> /// An expression to test each entity for a condition. /// </param> /// <returns> /// All entities matching the specified predicate within the current <see cref="DataAccessRepository{TEntity}" />. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="predicate" /> is <see langword="null" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public IQueryable <TEntity> FindWhere(Expression <Func <TEntity, Boolean> > predicate) { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); return(FindWhere(predicate.RejectIf().IsNull(nameof(predicate)), controlToken)); } }
/// <summary> /// Returns all entities from the current <see cref="DataAccessRepository{TEntity}" />. /// </summary> /// <returns> /// All entities within the current <see cref="DataAccessRepository{TEntity}" />. /// </returns> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public IQueryable <TEntity> All() { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); return(All(controlToken)); } }
/// <summary> /// Adds the specified entity to the current <see cref="DataAccessRepository{TEntity}" />. /// </summary> /// <param name="entity"> /// The entity to add. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="entity" /> is <see langword="null" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public void Add(TEntity entity) { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); Add(entity.RejectIf().IsNull(nameof(entity)).TargetArgument, controlToken); } }
/// <summary> /// Returns the number of entities in the current <see cref="DataAccessRepository{TEntity}" />. /// </summary> /// <returns> /// The number of entities in the current <see cref="DataAccessRepository{TEntity}" />. /// </returns> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public Int64 Count() { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); return(Count(controlToken)); } }
/// <summary> /// Gets the element at the specified index. /// </summary> /// <param name="index"> /// The index of the object to access. /// </param> /// <returns> /// The element at the specified index if one exists. /// </returns> /// <exception cref="IndexOutOfRangeException"> /// The specified index is out of range. /// </exception> public T this[Int32 index] { get { using (var controlToken = StateControl.Enter()) { var adjustedIndex = (ReadIndex + index); return (adjustedIndex < Capacity) ? ElementArray[adjustedIndex] : ElementArray[adjustedIndex - Capacity]; } } }
private ITopicClient CreateTopicClient <TMessage>() where TMessage : class { var topicPath = GetTopicPath <TMessage>(); using (var controlToken = StateControl.Enter()) { controlToken.AttachTask(EnsureTopicExistanceAsync(topicPath)); } return(new TopicClient(Connection, topicPath, RetryBehavior)); }
private IQueueClient CreateQueueClient <TMessage>() where TMessage : class { var queuePath = GetQueuePath <TMessage>(); using (var controlToken = StateControl.Enter()) { controlToken.AttachTask(EnsureQueueExistanceAsync(queuePath)); } return(new QueueClient(Connection, queuePath, ReceiveBehavior, RetryBehavior)); }
/// <summary> /// Unblocks waiting threads and ends the execution lifetime. /// </summary> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public void End() { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (IsAlive) { EndOfLifeEvent.Set(); IsAlive = false; } } }
private ISubscriptionClient CreateSubscriptionClient <TMessage>() where TMessage : class { var topicPath = GetTopicPath <TMessage>(); var subscriptionName = GetSubscriptionName <TMessage>(); using (var controlToken = StateControl.Enter()) { controlToken.AttachTask(EnsureSubscriptionExistanceAsync(topicPath, subscriptionName)); } return(new SubscriptionClient(Connection, topicPath, subscriptionName, ReceiveBehavior, RetryBehavior)); }
/// <summary> /// Blocks the current thread until <see cref="End" /> or <see cref="Dispose" /> is invoked. /// </summary> /// <exception cref="InvalidOperationException"> /// The service execution lifetime has ended. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public void KeepAlive() { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (IsAlive == false) { throw new InvalidOperationException("The service execution lifetime has ended."); } } EndOfLifeEvent.WaitOne(); }
/// <summary> /// Updates the specified entities in the current <see cref="DataAccessRepository{TEntity}" />. /// </summary> /// <param name="entities"> /// The entities to update. /// </param> /// <exception cref="ArgumentException"> /// <paramref name="entities" /> contains one or more null references. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="entities" /> is <see langword="null" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public void UpdateRange(IEnumerable <TEntity> entities) { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (entities.RejectIf().IsNull(nameof(entities)).TargetArgument.Any(entity => entity is null)) { throw new ArgumentException("The specified entity collection contains one or more null entities.", nameof(entities)); } UpdateRange(entities, controlToken); } }
/// <summary> /// Instructs the current <see cref="ReferenceManager" /> to manage the specified object. /// </summary> /// <typeparam name="T"> /// The type of the managed object. /// </typeparam> /// <param name="reference"> /// The managed object. /// </param> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public void AddObject <T>(T reference) where T : class { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); var managedReference = new ManagedReference <T>(reference); if (References.Contains(managedReference) == false) { References.Enqueue(managedReference); } } }
/// <summary> /// Updates the specified entity in the current <see cref="DataAccessRepository{TEntity}" />, or adds it if it doesn't exist. /// </summary> /// <param name="entity"> /// The entity to add or update. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="entity" /> is <see langword="null" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public void AddOrUpdate(TEntity entity) { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (Contains(entity.RejectIf().IsNull(nameof(entity)).TargetArgument, controlToken)) { Update(entity, controlToken); return; } Add(entity, controlToken); } }
/// <summary> /// Releases all resources consumed by the current <see cref="AzureServiceBusClientManager" />. /// </summary> /// <param name="disposing"> /// A value indicating whether or not managed resources should be released. /// </param> protected override void Dispose(Boolean disposing) { try { if (disposing) { using (var controlToken = StateControl.Enter()) { if (LazyReceiveClientDictionary.IsValueCreated) { foreach (var client in ReceiveClientDictionary.Values) { if (client.IsClosedOrClosing) { continue; } if (client is SubscriptionClient subscriptionClient) { ClientFactory.DestroySubscription(subscriptionClient.TopicPath, subscriptionClient.SubscriptionName); } controlToken.AttachTask(client.CloseAsync()); } } if (LazySendClientDictionary.IsValueCreated) { foreach (var client in SendClientDictionary.Values) { if (client.IsClosedOrClosing) { continue; } controlToken.AttachTask(client.CloseAsync()); } } } ClientFactory.Dispose(); } } finally { base.Dispose(disposing); } }
/// <summary> /// Converts the value of the current <see cref="CascadingSymmetricKey" /> to its equivalent binary representation. /// </summary> /// <returns> /// A binary representation of the current <see cref="CascadingSymmetricKey" />. /// </returns> public SecureBuffer ToBuffer() { var result = new SecureBuffer(SerializedLength); try { using (var controlToken = StateControl.Enter()) { result.Access(pinnedResultBuffer => { var keyLength = SecureSymmetricKey.SerializedLength; for (var i = 0; i < MaximumDepth; i++) { if (i < Depth) { using (var keyBuffer = Keys[i].ToBuffer()) { keyBuffer.Access(pinnedKeyBuffer => { // Copy the key buffers out to the result buffer. Array.Copy(pinnedKeyBuffer, 0, pinnedResultBuffer, (keyLength * i), keyLength); }); } continue; } // Fill the unused segments with random bytes. var randomBytes = new Byte[keyLength]; HardenedRandomNumberGenerator.Instance.GetBytes(randomBytes); Array.Copy(randomBytes, 0, pinnedResultBuffer, (keyLength * i), keyLength); } // Append the depth as a 16-bit integer. Buffer.BlockCopy(BitConverter.GetBytes(Convert.ToUInt16(Depth)), 0, pinnedResultBuffer, (SerializedLength - sizeof(UInt16)), sizeof(UInt16)); }); return(result); } } catch { result.Dispose(); throw new SecurityException("Key serialization failed."); } }
/// <summary> /// Writes an element at the tail of the current <see cref="CircularBuffer{T}" />. /// </summary> /// <param name="element"> /// The element to write to the buffer. /// </param> public void Write(T element) { using (var controlToken = StateControl.Enter()) { ElementArray[WriteIndex] = element; if (Length < Capacity) { Length++; } if (++WriteIndex == Capacity) { WriteIndex = 0; } } }
/// <summary> /// Commits all changes made within the scope of the current <see cref="DataAccessTransaction" />. /// </summary> /// <exception cref="InvalidOperationException"> /// <see cref="State" /> is not equal to <see cref="DataAccessTransactionState.InProgress" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public void Commit() { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (State == DataAccessTransactionState.InProgress) { State = DataAccessTransactionState.Committed; Commit(controlToken); } else { throw new InvalidOperationException($"{nameof(Commit)} cannot be invoked when the transaction state is {State.ToString()}."); } } }
/// <summary> /// Asynchronously initiates the current <see cref="IDataAccessTransaction" />. /// </summary> /// <returns> /// A task representing the asynchronous operation. /// </returns> /// <exception cref="InvalidOperationException"> /// <see cref="State" /> is not equal to <see cref="DataAccessTransactionState.Ready" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public async Task BeginAsync() { using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (State == DataAccessTransactionState.Ready) { State = DataAccessTransactionState.InProgress; await BeginAsync(controlToken).ConfigureAwait(false); } else { throw new InvalidOperationException($"{nameof(Commit)} cannot be invoked when the transaction state is {State.ToString()}."); } } }
/// <summary> /// Simulates a thread-safe operation. /// </summary> public void SimulateThreadSafeOperation() { using (var controlToken = StateControl.Enter()) { lock (SyncRoot) { ConcurrencyCount++; } Thread.Sleep(ThreadSafeOperationDelayDuration); lock (SyncRoot) { ConcurrencyCount--; } } }
/// <summary> /// Converts the value of the current <see cref="SecureSymmetricKey" /> to its equivalent binary representation. /// </summary> /// <returns> /// A binary representation of the current <see cref="SecureSymmetricKey" />. /// </returns> public SecureBuffer ToBuffer() { var resultBuffer = new SecureBuffer(SerializedLength); try { using (var controlToken = StateControl.Enter()) { using (var plaintextBuffer = new PinnedBuffer(SerializedPlaintextLength, true)) { KeySource.Access(pinnedKeySourceBuffer => { Array.Copy(pinnedKeySourceBuffer, 0, plaintextBuffer, KeySourceBufferIndex, KeySourceLengthInBytes); }); plaintextBuffer[AlgorithmBufferIndex] = (Byte)Algorithm; plaintextBuffer[DerivationModeBufferIndex] = (Byte)DerivationMode; using (var cipher = BufferEncryptionAlgorithm.ToCipher(RandomnessProvider)) { using (var initializationVector = new PinnedBuffer(cipher.BlockSizeInBytes, true)) { RandomnessProvider.GetBytes(initializationVector); resultBuffer.Access(pinnedResultBuffer => { using (var ciphertext = cipher.Encrypt(plaintextBuffer, BufferEncryptionKey, initializationVector)) { Array.Copy(ciphertext, 0, pinnedResultBuffer, 0, SerializedLength); } }); } } } } return(resultBuffer); } catch { resultBuffer.Dispose(); throw new SecurityException("Key serialization failed."); } }
/// <summary> /// Calculates hash values for the specified ordered data block collection and adds them to the tree. /// </summary> /// <param name="blocks"> /// An ordered collection of data block objects to add to the hash tree. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="blocks" /> is <see langword="null" /> -or- <paramref name="blocks" /> contains a null data block object. /// </exception> /// <exception cref="SecurityException"> /// An exception was raised during hashing or serialization. /// </exception> public void AddBlockRange(IEnumerable <TBlock> blocks) { if (blocks.Any() == false) { return; } using (var controlToken = StateControl.Enter()) { var newNodes = blocks.RejectIf().IsNull(nameof(blocks)).TargetArgument.Select(block => CalculateHash(block.RejectIf().IsNull(nameof(blocks)).TargetArgument)).Select(hashValue => new HashTreeNode(hashValue)); foreach (var node in newNodes) { LeafNodes.Add(node); } PermuteRow(LeafNodes); } }
/// <summary> /// Gets a shared, managed <see cref="IReceiverClient" /> instance. /// </summary> /// <typeparam name="TMessage"> /// The type of the message that the client handles. /// </typeparam> /// <param name="entityType"> /// The type of the entity. /// </param> /// <returns> /// The managed <see cref="IReceiverClient" /> instance. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="entityType" /> is equal to <see cref="MessagingEntityType.Unspecified" />. /// </exception> /// <exception cref="MessageSubscriptionException"> /// An exception was raised while creating the client. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> public IReceiverClient GetReceiveClient <TMessage>(MessagingEntityType entityType) where TMessage : class { var entityPath = GetEntityPath <TMessage>(entityType); using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (ReceiveClientDictionary.TryGetValue(entityPath, out var client)) { return(client); } client = ClientFactory.CreateReceiveClient <TMessage>(entityType); ReceiveClientDictionary.Add(entityPath, client); return(client); } }
/// <summary> /// Returns the instance of specified type that is managed by the current <see cref="IFactoryProducedInstanceGroup" />. /// </summary> /// <typeparam name="T"> /// The type of the instance to return. /// </typeparam> /// <returns> /// The instance of specified type that is managed by the current <see cref="IFactoryProducedInstanceGroup" />. /// </returns> /// <exception cref="ArgumentException"> /// <typeparamref name="T" /> is not a supported type for the group. /// </exception> /// <exception cref="ObjectDisposedException"> /// The object is disposed. /// </exception> /// <exception cref="ObjectProductionException"> /// An exception was raised during object production. /// </exception> public T Get <T>() where T : class { var instanceType = typeof(T); using (var controlToken = StateControl.Enter()) { RejectIfDisposed(); if (Instances.TryGetValue(instanceType, out var extantInstance)) { return(extantInstance as T); } var newInstance = Factory.Produce(instanceType) as T; Instances.Add(instanceType, newInstance); ReferenceManager.AddObject(newInstance); return(newInstance); } }