Accessing and Manipulating Data in Dataverse with the XRM Client

Accessing and Manipulating Data in Dataverse with the XRM Client Using the XRM client, you can perform CRUD (Create, Read, Update, Delete) operations and retrieve related data in Microsoft Dataverse. This guide walks you through these tasks step-by-step. Setup Ensure the following packages are installed: Install-Package Microsoft.CrmSdk.XrmTooling.CoreAssembly Install-Package Microsoft.CrmSdk.XrmTooling.CrmWebApi Connect to Dataverse Establish a connection to your Dataverse environment: using Microsoft.Xrm.Tooling.Connector; using Microsoft.Xrm.Sdk; var connectionString = "AuthType=OAuth;Username=YOUR_USERNAME;Password=YOUR_PASSWORD;Url=https://YOUR_ORG.crm.dynamics.com;AppId=YOUR_APP_ID;RedirectUri=YOUR_REDIRECT_URI;"; var service = new CrmServiceClient(connectionString); 1. Read (Retrieve) Operation Retrieve an entity record by its ID: ...

March 15, 2025 · 3 min · Taner

Automating FusionCache with a Source Generator: A Step-by-Step Guide

Automating FusionCache with a Source Generator: A Step-by-Step Guide Using a source generator to automate code for calling the GetOrSetAsync function from FusionCache is an elegant way to handle caching. Let’s walk through how you can use Roslyn, the .NET Compiler Platform, to create a generator tailored to your needs. Step 1: Create the Custom Attribute Start by defining a FusionCacheAttribute that will decorate the methods you want to cache: ...

March 15, 2025 · 2 min · Taner

Complete Implementation of a Message Envelope Using Newtonsoft.Json

Complete Implementation using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; // For serialization and deserialization public abstract class MessageEnvelope<T> { // Immutable properties public string EventType { get; private init; } public string SourceService { get; private init; } public DateTime Timestamp { get; private init; } public Guid TraceId { get; private init; } public T Payload { get; private init; } // Private constructor to enforce the use of the builder private MessageEnvelope() { } // Static method to start building the envelope public static Builder CreateBuilder() => new Builder(); // Nested Builder class public class Builder { private readonly MessageEnvelope<T> _envelope = new ConcreteMessageEnvelope(); public Builder WithEventType(string eventType) { if (string.IsNullOrWhiteSpace(eventType)) throw new ArgumentException("EventType cannot be null or empty"); _envelope.EventType = eventType; return this; } public Builder WithSourceService(string sourceService) { if (string.IsNullOrWhiteSpace(sourceService)) throw new ArgumentException("SourceService cannot be null or empty"); _envelope.SourceService = sourceService; return this; } public Builder WithPayload(T payload) { _envelope.Payload = payload; return this; } public Builder WithTimestamp(DateTime timestamp) { _envelope.Timestamp = timestamp; return this; } public Builder WithTraceId(Guid traceId) { _envelope.TraceId = traceId; return this; } public Builder WithoutPayload() { _envelope.Payload = default; return this; } public MessageEnvelope<T> Build() { // Set defaults if not already set _envelope.EventType ??= "Unknown"; _envelope.Timestamp = _envelope.Timestamp == default ? DateTime.UtcNow : _envelope.Timestamp; _envelope.TraceId = _envelope.TraceId == default ? Guid.NewGuid() : _envelope.TraceId; return _envelope; } } // Clone method to replicate an envelope with modifications public MessageEnvelope<T> Clone() { return CreateBuilder() .WithEventType(this.EventType) .WithSourceService(this.SourceService) .WithPayload(this.Payload) .WithTimestamp(this.Timestamp) .WithTraceId(this.TraceId) .Build(); } // Serialization to JSON public string ToJson() { return JsonConvert.SerializeObject(this); } // Deserialization from JSON public static MessageEnvelope<T> FromJson(string json) { return JsonConvert.DeserializeObject<ConcreteMessageEnvelope>(json); } // Batch creation for multiple payloads public static IEnumerable<MessageEnvelope<T>> CreateBatch(IEnumerable<T> payloads, string eventType, string sourceService) { return payloads.Select(payload => CreateBuilder() .WithEventType(eventType) .WithSourceService(sourceService) .WithPayload(payload) .Build()); } // Example of a concrete implementation private class ConcreteMessageEnvelope : MessageEnvelope<T> { } } Examples 1. Basic Envelope Creation var envelope = MessageEnvelope<Reservation> .CreateBuilder() .WithEventType("ReservationExpiry") .WithSourceService("ReservationService") .WithPayload(new Reservation { ReservationId = "res-001", SlotId = "slot-123", ExpiryTime = DateTime.UtcNow }) .Build(); Console.WriteLine(envelope.ToJson()); 2. Creating an Envelope Without Payload var metadataOnlyEnvelope = MessageEnvelope<object> .CreateBuilder() .WithEventType("SystemEvent") .WithSourceService("MonitoringService") .WithoutPayload() .Build(); 3. Cloning an Envelope var clonedEnvelope = envelope.Clone(); Console.WriteLine(clonedEnvelope.ToJson()); 4. Batch Creation var reservations = new List<Reservation> { new Reservation { ReservationId = "res-001", SlotId = "slot-123", ExpiryTime = DateTime.UtcNow }, new Reservation { ReservationId = "res-002", SlotId = "slot-456", ExpiryTime = DateTime.UtcNow.AddHours(1) } }; var envelopes = MessageEnvelope<Reservation>.CreateBatch(reservations, "ReservationExpiry", "ReservationService"); foreach (var env in envelopes) { Console.WriteLine(env.ToJson()); } 5. Serialization and Deserialization string serialized = envelope.ToJson(); var deserialized = MessageEnvelope<Reservation>.FromJson(serialized); Console.WriteLine($"Deserialized TraceId: {deserialized.TraceId}"); Conclusion This implementation leverages Newtonsoft.Json to serialize and deserialize objects efficiently. The inclusion of batch creation, cloning, and flexibility makes this envelope a robust solution for designing reliable messaging systems in distributed architectures. ...

March 15, 2025 · 3 min · Taner

Implementing Distributed Locking with Redis and IDistributedLock

Implementing Distributed Locking with Redis and IDistributedLock Distributed locking is a critical feature for ensuring resource safety in distributed applications. Here’s how you can implement a distributed lock using the IDistributedLock interface and Redis as the backing store, leveraging the StackExchange.Redis library. Step 1: Implement the IDistributedLock Interface Let’s start by creating the RedisDistributedLock class to implement the IDistributedLock interface: using StackExchange.Redis; using System; using System.Threading.Tasks; public class RedisDistributedLock : IDistributedLock { private readonly IDatabase _database; private readonly string _lockKey; private string _lockToken; public RedisDistributedLock(IDatabase database, string lockKey) { _database = database; _lockKey = lockKey; _lockToken = Guid.NewGuid().ToString(); } public async Task<bool> AcquireLockAsync(string resource, TimeSpan leaseTime) { _lockToken = Guid.NewGuid().ToString(); return await _database.StringSetAsync(resource, _lockToken, leaseTime, When.NotExists); } public async Task RenewLockAsync(TimeSpan leaseTime) { if (!await _database.StringGetAsync(_lockKey).ConfigureAwait(false).Equals(_lockToken)) { throw new InvalidOperationException("Cannot renew a lock that is not held."); } await _database.KeyExpireAsync(_lockKey, leaseTime); } public async Task ReleaseLockAsync() { var token = await _database.StringGetAsync(_lockKey); if (token == _lockToken) { await _database.KeyDeleteAsync(_lockKey); } } public void Dispose() { ReleaseLockAsync().GetAwaiter().GetResult(); } } Step 2: Create a Sample Console Application Next, build a console application to demonstrate the functionality of the RedisDistributedLock: ...

March 15, 2025 · 2 min · TC

Mastering Aspect-Oriented Programming (AOP): Concepts and Examples

Mastering Aspect-Oriented Programming (AOP): Concepts and Examples Aspect-Oriented Programming (AOP) is a programming paradigm that takes modularity to the next level. It allows you to neatly separate cross-cutting concerns like logging, security, or transaction management from your main business logic. Think of it as an enhancement to Object-Oriented Programming (OOP) that brings even more structure and reusability to your codebase. link to link to Key Concepts of AOP Here’s a quick dive into the foundational elements of AOP: ...

March 15, 2025 · 2 min · Taner

Mastering Aspect-Oriented Programming (AOP): Concepts and Examples

To create a code generator that automatically caches any function with a cache attribute that takes a duration, you can use a source generator in .NET. Source generators allow you to generate additional source code at compile time. Step 1: Define the Cache Attribute First, define the cache attribute that will be used to mark methods for caching: using System; [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] public sealed class CacheAttribute : Attribute { public CacheAttribute(int durationInSeconds) { DurationInSeconds = durationInSeconds; } public int DurationInSeconds { get; } } Step 2: Create the Source Generator Next, create the source generator that will generate the caching logic for methods marked with the CacheAttribute. ...

March 15, 2025 · 3 min · Taner

Mastering Aspect-Oriented Programming (AOP): Concepts and Examples

RedisDistributedLock Implementation in Aspect-Oriented Programming (AOP) Aspect-Oriented Programming (AOP) lends itself well to distributed resource management tasks such as locking. Below is an implementation of a Redis-based distributed lock using the StackExchange.Redis library, focusing on resource isolation and concurrency control. RedisDistributedLock Class Here is the complete implementation: using StackExchange.Redis; using System; using System.Threading.Tasks; public class RedisDistributedLock : IDisposable { private readonly IDatabase _redisDb; private readonly string _lockKey; private readonly string _lockValue; private bool _acquired; public RedisDistributedLock(IDatabase redisDb, string resourceKey) { _redisDb = redisDb; _lockKey = $"lock:{resourceKey}"; _lockValue = Guid.NewGuid().ToString(); // random token } /// <summary> /// Attempts to acquire a lock for the specified lock key with a given expiry. /// </summary> /// <param name="expiry">Duration for lock expiry.</param> /// <returns>True if the lock was acquired; otherwise, false.</returns> public async Task<bool> AcquireAsync(TimeSpan expiry) { _acquired = await _redisDb.StringSetAsync( key: _lockKey, value: _lockValue, expiry: expiry, when: When.NotExists); return _acquired; } /// <summary> /// Releases the lock if it’s still held by this instance. /// </summary> public async Task ReleaseAsync() { if (_acquired) { // Verify token before deleting. var currentValue = await _redisDb.StringGetAsync(_lockKey); if (currentValue == _lockValue) { await _redisDb.KeyDeleteAsync(_lockKey); } _acquired = false; } } /// <summary> /// Cleanup method ensuring the lock is freed. /// </summary> public void Dispose() { ReleaseAsync().GetAwaiter().GetResult(); } } Acquiring and Releasing the Lock Using the RedisDistributedLock class to acquire and release locks ensures concurrency control in distributed systems. ...

March 15, 2025 · 2 min · Taner

Mastering the Retry Pattern: Enhancing Application Resiliency

Mastering the Retry Pattern: Enhancing Application Resiliency The retry pattern is a crucial design technique for improving the resiliency of applications, especially when dealing with transient faults in external systems. Let’s explore its purpose, implementation, and how it contributes to robust architecture. Purpose of the Retry Pattern Automatic Retries: Enables applications to automatically retry a failed operation due to transient faults. Graceful Error Handling: Improves user experience by addressing errors seamlessly. Increased Reliability: Allows applications to recover from temporary issues, ensuring dependable performance. Key Concepts of the Retry Pattern Transient Faults: Temporary issues like network glitches, timeouts, or service throttling that are likely to succeed upon retry. Retry Interval: The delay between attempts, which can follow a fixed interval, exponential backoff, or a custom logic. Max Retry Attempts: Specifies the maximum number of retries before declaring the operation as failed. Implementation Example in C# Here’s how to implement a retry pattern using C#: ...

March 15, 2025 · 3 min · TC

Performing CRUD Operations and Joining Tables with IOrganizationService

Performing CRUD Operations and Joining Tables with IOrganizationService When working with Microsoft Dataverse, IOrganizationService is a powerful API that enables direct interaction with the Dataverse environment. This guide demonstrates how to perform CRUD operations and retrieve related records using the OrganizationService in an ASP.NET Core application. Setup Before starting, ensure the required packages are installed: Install-Package Microsoft.CrmSdk.CoreAssemblies Install-Package Microsoft.CrmSdk.XrmTooling.CoreAssembly Connect to Dataverse Establish a connection to your Dataverse environment using a connection string: ...

March 15, 2025 · 2 min · Taner

Setting Up a Development Environment for SharePoint with Microsoft Graph API

Setting Up a Development Environment for SharePoint with Microsoft Graph API Setting up a development environment for SharePoint, especially one integrated with the Microsoft Graph API, doesn’t have to be daunting! This guide breaks it down step by step. 1. Choose Your SharePoint Environment You have two main options: SharePoint Online (Office 365): Perfect for Microsoft Graph integration—always current and feature-rich. SharePoint Server (On-Premises): More complex and doesn’t directly support Microsoft Graph. For beginners, SharePoint Online is a no-brainer! ...

March 15, 2025 · 2 min · TC