Real Web Developers

NHibernate helpers


namespace RealWebDevelopers;
public static partial class Extensions
{
    public static IServiceCollection AddNHibernate(this IServiceCollection services)
    {
        services.AddSingleton(factory =>
        {
            // ...
            return Fluently
                .Configure()
                .Database(MySQLConfiguration.Standard
                    .ConnectionString(options.ConnectionString)
                    .ShowSql())
                .Mappings(mappings => mappings.AutoMappings.Add(AutoMap.AssemblyOf()
                        .Where(where => where.Namespace!.Equals("TradingApplication.Models", StringComparison.OrdinalIgnoreCase))
                        .Override(populateMap =>
                        {
                            populateMap.Id(memberExpression => memberExpression.Reference).Not.Nullable().Length(31).GeneratedBy.Assigned();

                            // the next line sets this as the parent. Note the KeyColumn is the name of the column on the Child entity which holds a reference to this Parent
                            populateMap.HasMany(memberExpression => memberExpression.Children).Cascade.AllDeleteOrphan().Inverse().KeyColumn("ParentReference");
                        })
                        .Override(populateMap =>
                        {
                            populateMap.Id(memberExpression => memberExpression.Reference).Not.Nullable().Length(31).GeneratedBy.Assigned();
                            populateMap.References(memberExpression => memberExpression.Parent).Column("ParentReference");
                        })
            // ...
        });
    }
}
    
  • Full article
  • Service collection Fluent Nhibernate

    namespace RealWebDevelopers;
    
    using FluentNHibernate.Automapping;
    using FluentNHibernate.Cfg;
    using FluentNHibernate.Cfg.Db;
    using Microsoft.Extensions.Options;
    using NHibernate;
    using NHibernate.Tool.hbm2ddl;
    using Models;
    
    public static class Extensions
    {
        public static IServiceCollection AddNHibernate(this IServiceCollection services)
        {
            services.AddSingleton<ISessionFactory>(implementationFactory =>
            {
                var options = implementationFactory.GetRequiredService<IOptions<NHibernateOptions>>().Value;
                return Fluently.Configure()
                    .Database(MySQLConfiguration.Standard
                        .ConnectionString(options.ConnectionString)
                        .ShowSql())
                    .Mappings(mappings => mappings.AutoMappings.Add(AutoMap.AssemblyOf<Program>()
                        .Where(where => where.Namespace!.Equals("CrmPolicyMessageSubscriber.Models", StringComparison.OrdinalIgnoreCase))
                        .Override<Customer>(populateMap =>
                        {
                            populateMap.Id(memberExpression => memberExpression.Reference).Not.Nullable().Length(31);
                            populateMap.Map(memberExpression => memberExpression.FirstName).Not.Nullable().Length(127);
                            populateMap.Map(memberExpression => memberExpression.LastName).Not.Nullable().Length(127);
                            populateMap.Map(memberExpression => memberExpression.EmailAddress).Not.Nullable().Length(127);
                            populateMap.Map(memberExpression => memberExpression.PhoneNumber).Nullable().Length(31);
                            populateMap.Map(memberExpression => memberExpression.AddressLine1).Not.Nullable().Length(127);
                            populateMap.Map(memberExpression => memberExpression.AddressLine2).Not.Nullable().Length(127);
                            // ...
                        })))
                    .ExposeConfiguration(config =>
                    {
                        config.Properties.Add("current_session_context", options.SessionContext);
                        new SchemaUpdate(config).Execute(true, true);
                    })
                    .BuildSessionFactory();
            });
            services.AddScoped<ISession>(implementationFactory => { return implementationFactory.GetRequiredService<ISessionFactory>().OpenSession(); });
            return services;
        }
    }
        
    
    Full article

    MemoryCache

    
    namespace RealWebDevelopers;
    
    public class Provider
    {
        private readonly IMemoryCache memoryCache;
        private readonly MemoryCacheEntryOptions memoryCacheEntryOptions = new MemoryCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); // Cache for 1 hour
        }
    
        public Provider(IMemoryCache memoryCache)
        {
            this.memoryCache = memoryCache;
        }
    
        public IEnumberable<Product> GetProducts()
        {
            var cacheKey = "product";
            if (!this.memoryCache.TryGetValue(cacheKey, out List<Product> productCache))
            {
                try
                {
                    // Fetch the data from source i.e. Database query
                    var products = this.session.Query<Product>();
                    this.memoryCache.Set(cacheKey, products, this.memoryCacheEntryOptions);
                    return products;
                }
                catch
                {
                    // Whatever
                }
            }
    
            return productCache;
        }
    }
    
    
    Full article

    Service collection Jaeger

    namespace RealWebDevelopers;
    
    using Microsoft.Extensions.Options;
    using OpenTelemetry.Resources;
    using OpenTelemetry.Trace;
    
    public class Program
    {
        public static void Main(string[] args)
        {
            // boiler plate web application
            builder.Services.AddOpenTelemetry()
                .WithTracing(configure =>
                {
                    configure.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(builder.Environment.ApplicationName))
                        .AddAspNetCoreInstrumentation()
                        .AddHttpClientInstrumentation()
                        .AddSource(builder.Environment.ApplicationName)
                        .AddOtlpExporter(config => { config.Endpoint = new Uri("http://localhost:4317"); });
                });
    
            // etc.
        }
    }
    
    
    Full article

    Case-insensitive Dictionary access in C#

    namespace RealWebDevelopers;
    
    using System;
    using System.Collections.Generic;
    
    public static class Program
    {
      private static readonly Dictionary cache = new(StringComparer.OrdinalIgnoreCase)
      {
        {
          "dog", "woof"
        },
        {
          "cat", "meow"
        };
      };
    
      public static void Main(string[] args)
      {
        Console.Write(cache.GetValueOrDefault("dog"));
        Console.Write(cache.GetValueOrDefault("Dog"));
      }
    }
      
    
    Full article

    Service Collection RabbitMQ extension

    namespace RealWebDevelopers;
    
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Options;
    using RabbitMQ.Client;
    
    public static class Extensions
    {
        public static void AddRabbitMq(this ServiceCollection services)
        {
            services.AddSingleton(implementationFactory =>
            {
                return new ConnectionFactory
                {
                    HostName = implementationFactory.GetRequiredService>().Value.Host,
                }.CreateConnectionAsync().Result;
            });
            return services;
        }
    }
      
    
    Full article