Skip to content

Instantly share code, notes, and snippets.

@oguzhaneren
Last active January 14, 2019 10:42
Show Gist options
  • Save oguzhaneren/06bbfb0913c205b55c885584720a6f90 to your computer and use it in GitHub Desktop.
Save oguzhaneren/06bbfb0913c205b55c885584720a6f90 to your computer and use it in GitHub Desktop.
C# Extensions & Helpers
public static class AssemblyExtensions
{
public static IEnumerable<T> ExtractInstances<T>(this Assembly assembly)
{
return assembly.ExtractClasses<T>()
.Select(q => q.GetConstructors().First(x => !x.GetParameters().Any()))
.Select(i => i.Invoke(null))
.Cast<T>();
}
public static IEnumerable<Type> ExtractClasses<T>(this Assembly assembly)
{
return assembly.GetTypes()
.Where(i =>
i.GetInterfaces().Any(iface => iface == typeof(T)) &&
i.GetConstructors().Any(x => !x.GetParameters().Any()));
}
public static IEnumerable<Type> ExtractClasses(this Assembly assembly, Type type)
{
return assembly.GetTypes()
.Where(i => i.GetInterfaces().Any(iface => (iface.FullName ?? "").StartsWith(type.FullName)) &&
i.GetConstructors().Any(x => !x.GetParameters().Any()));
}
}
public static class AutoMapperExtensions
{
public static IMappingExpression<TSource, TDestination> ConditionForAllProperties<TSource, TDestination, TFilter>(
this IMappingExpression<TSource, TDestination> expression,
Func<PropertyInfo, TFilter> filter,
Func<TFilter, TSource, bool> condition)
where TFilter : class
{
if (filter == null)
throw new ArgumentNullException("filter");
if (condition == null)
throw new ArgumentNullException("condition");
var sourceType = typeof(TSource);
foreach (var property in sourceType.GetProperties())
{
var f = filter(property);
if (f == null)
{
expression.ForMember(property.Name, opt => opt.Condition(x => condition(f, x)));
}
// expression.ForMember(property.Name, opt => opt.Ignore());
}
return expression;
}
public static List<TResult> MapTo<TResult>(this IEnumerable self)
{
if (self == null)
throw new ArgumentNullException();
return (List<TResult>) Mapper.Map(self, self.GetType(), typeof (List<TResult>));
}
public static TResult MapTo<TResult>(this object self)
{
if (self == null)
throw new ArgumentNullException();
return (TResult) Mapper.Map(self, self.GetType(), typeof (TResult));
}
public static TResult MapPropertiesToInstance<TResult>(this object self, TResult value)
{
if (self == null)
throw new ArgumentNullException();
return (TResult) Mapper.Map(self, value, self.GetType(), typeof (TResult));
}
public static TResult DynamicMapTo<TResult>(this object self)
{
if (self == null)
throw new ArgumentNullException();
return (TResult) Mapper.DynamicMap(self, self.GetType(), typeof (TResult));
}
}
public static class AzureConManagerSqlPersistenceWireupExtensions
{
public static SqlPersistenceWireup UseInAzureConfiguredSqlPersistence(this Wireup wireup, string connectionName)
{
var factory = new AzureConfigurationConnectionFactory(connectionName);
return new SqlPersistenceWireup(wireup, factory);
}
}
public class AzureConfigurationConnectionFactory : ConfigurationConnectionFactory
{
private const string providerType = "System.Data.SqlClient";
public AzureConfigurationConnectionFactory(string connectionName)
: base(connectionName)
{
}
protected override ConnectionStringSettings GetConnectionStringSettings(string connectionName)
{
var connectionString = TypedCloudConfigurationManager.GetSetting(connectionName);
return new ConnectionStringSettings(connectionName, connectionString, providerType);
}
protected override IDbConnection Open(string connectionString, ConnectionStringSettings setting)
{
var connection = new ReliableSqlConnection(connectionString);
connection.Open();
return connection;
}
}
public class ReliableSqlCommand : IDbCommand
{
private static readonly Policy RetryPolicy = Policy
.Handle<SqlException>(ex => ex.Number == 11001 || ex.Number == 1205)
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
});
public ReliableSqlCommand()
{
RealCommand = new SqlCommand();
}
public ReliableSqlCommand(string commandText)
{
RealCommand = new SqlCommand(commandText);
}
public ReliableSqlCommand(string commandText, SqlConnection connection)
{
RealCommand = new SqlCommand(commandText, connection);
}
public ReliableSqlCommand(string commandText, SqlConnection connection, SqlTransaction transaction)
{
RealCommand = new SqlCommand(commandText, connection, transaction);
}
protected SqlCommand RealCommand { get; set; }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Prepare()
{
RealCommand.Prepare();
}
public void Cancel()
{
RealCommand.Cancel();
}
public IDbDataParameter CreateParameter()
{
return RealCommand.CreateParameter();
}
public int ExecuteNonQuery()
{
return RetryPolicy.Execute(() => RealCommand.ExecuteNonQuery());
}
public IDataReader ExecuteReader()
{
return RetryPolicy.Execute(() => RealCommand.ExecuteReader());
}
public IDataReader ExecuteReader(CommandBehavior behavior)
{
return RetryPolicy.Execute(() => RealCommand.ExecuteReader(behavior));
}
public object ExecuteScalar()
{
return RetryPolicy.Execute(() => RealCommand.ExecuteScalar());
}
public IDbConnection Connection
{
get { return RealCommand.Connection; }
set { RealCommand.Connection = value as SqlConnection; }
}
public IDbTransaction Transaction
{
get { return RealCommand.Transaction; }
set { RealCommand.Transaction = value as SqlTransaction; }
}
public string CommandText
{
get { return RealCommand.CommandText; }
set { RealCommand.CommandText = value; }
}
public int CommandTimeout
{
get { return RealCommand.CommandTimeout; }
set { RealCommand.CommandTimeout = value; }
}
public CommandType CommandType
{
get { return RealCommand.CommandType; }
set { RealCommand.CommandType = value; }
}
public IDataParameterCollection Parameters
{
get { return RealCommand.Parameters; }
}
public UpdateRowSource UpdatedRowSource
{
get { return RealCommand.UpdatedRowSource; }
set { RealCommand.UpdatedRowSource = value; }
}
private void Dispose(bool disposing)
{
if (disposing)
{
RealCommand.Dispose();
}
}
}
public class ReliableSqlConnection : IDbConnection
{
private static readonly Policy RetryPolicy = Policy
.Handle<SqlException>(ex => ex.Number == 11001)
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
});
public ReliableSqlConnection()
{
UnderlyingConnection = new SqlConnection();
}
public ReliableSqlConnection(string connectionString)
{
UnderlyingConnection = new SqlConnection(connectionString);
}
public SqlConnection UnderlyingConnection { get; set; }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (UnderlyingConnection.State == ConnectionState.Open)
{
UnderlyingConnection.Close();
}
UnderlyingConnection.Dispose();
}
}
public IDbTransaction BeginTransaction()
{
return UnderlyingConnection.BeginTransaction();
}
public IDbTransaction BeginTransaction(IsolationLevel il)
{
return UnderlyingConnection.BeginTransaction(il);
}
public void Close()
{
UnderlyingConnection.Close();
}
public void ChangeDatabase(string databaseName)
{
UnderlyingConnection.ChangeDatabase(databaseName);
}
public IDbCommand CreateCommand()
{
return new ReliableSqlCommand {Connection = UnderlyingConnection};
}
public void Open()
{
RetryPolicy.Execute(() =>
{
if (UnderlyingConnection.State != ConnectionState.Open)
{
UnderlyingConnection.Open();
}
});
}
public string ConnectionString { get { return UnderlyingConnection.ConnectionString; } set { UnderlyingConnection.ConnectionString = value; } }
public int ConnectionTimeout { get { return UnderlyingConnection.ConnectionTimeout; } }
public string Database { get { return UnderlyingConnection.Database; } }
public ConnectionState State { get { return UnderlyingConnection.State; } }
}
// https://patrickdesjardins.com/blog/lambda-utilities-to-get-nested-property-name-and-value
public class ExpressionHelper
{
private void BindDictionary(JToken token, Dictionary<string, string> dic, string parentName = null)
{
parentName = parentName ?? string.Empty;
var dot = string.IsNullOrEmpty(parentName) ? string.Empty : ".";
if (token is JValue)
{
dic.Add(parentName, token.Value<string>());
return;
}
foreach (JToken t in token)
{
if (t.Type == JTokenType.Property)
{
var prop = t as JProperty;
if (prop.Value.Type == JTokenType.Object)
{
BindDictionary(prop.Value, dic, $"{parentName}{dot}{prop.Name}");
}
else if (prop.Value.Type == JTokenType.Array)
{
int index = 0;
foreach (var a in prop.Value)
{
BindDictionary(a, dic, $"{parentName}{dot}{prop.Name}[{index}]");
index++;
}
}
else
{
dic.Add($"{parentName}{dot}{prop.Name}", prop.Value.ToString());
}
}
else if (t.Type == JTokenType.Object)
{
BindDictionary(t, dic, $"{parentName}{dot}");
}
else
{
var prop = t as JValue;
dic.Add($"{parentName}{dot}{prop}", t.ToString());
}
}
}
public static string GetPropertyName<T>(Expression<Func<T>> expression)
{
return GetPropertyNameOfExpression(expression);
}
public static string GetPropertyName<T>(Expression<Func<T,object>> expression)
{
return GetPropertyNameOfExpression(expression);
}
private static string GetPropertyNameOfExpression(LambdaExpression expression)
{
var stack = new Stack<string>();
Expression expression1 = expression.Body;
while (expression1 != null)
{
if (expression1.NodeType == ExpressionType.Call)
{
var methodCallExpression = (MethodCallExpression) expression1;
if (IsSingleArgumentIndexer(methodCallExpression))
{
stack.Push(string.Empty);
expression1 = methodCallExpression.Object;
}
else
break;
}
else if (expression1.NodeType == ExpressionType.ArrayIndex)
{
var binaryExpression = (BinaryExpression) expression1;
stack.Push(string.Empty);
expression1 = binaryExpression.Left;
}
else if (expression1.NodeType == ExpressionType.MemberAccess)
{
var memberExpression = (MemberExpression) expression1;
stack.Push("." + memberExpression.Member.Name);
expression1 = memberExpression.Expression;
}
else if (expression1.NodeType == ExpressionType.Parameter)
{
stack.Push(string.Empty);
expression1 = null;
}
else if (expression1.NodeType == ExpressionType.Convert)
{
var memberExp = ((UnaryExpression) expression1).Operand as MemberExpression;
stack.Push("." + memberExp.Member.Name);
expression1 = memberExp.Expression;
}
else
break;
}
if (stack.Count > 0 && string.Equals(stack.Peek(), ".model", StringComparison.OrdinalIgnoreCase))
stack.Pop();
if (stack.Count <= 0)
return string.Empty;
return (stack).Aggregate(((left, right) => left + right)).TrimStart(new[] {'.'});
}
private static bool IsSingleArgumentIndexer(Expression expression)
{
var methodExpression = expression as MethodCallExpression;
if (methodExpression == null || methodExpression.Arguments.Count != 1)
return false;
return (methodExpression.Method.DeclaringType.GetDefaultMembers()).OfType<PropertyInfo>().Any((p => p.GetGetMethod() == methodExpression.Method));
}
}
public static class NamedStringFormatExtension
{
public static string FormatByName(this string s, Dictionary<string, object> parameterdictionary)
{
return KeyValueReplacer(s, parameterdictionary);
}
public static string FormatByName(this string s, object parameterclass)
{
var d = PropertiesToDictionary(parameterclass);
return KeyValueReplacer(s, d);
}
private static Dictionary<string, object> PropertiesToDictionary(object o)
{
var t = o.GetType();
if (!t.IsClass)
throw new ArgumentException("Can only resolve properties in classes.");
var p = t.GetProperties();
var propcollection = p.ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(o, null));
return propcollection;
}
private static string KeyValueReplacer(string template, Dictionary<string, object> parametercollection)
{
// Get the parameters from the template
Regex m_regexmatch = new Regex(@"(?<start>\{)+(?<property>[\w\.\[\]]+)(?<format>:[^}]+)?(?<end>\})+",
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
var matches = m_regexmatch.Matches(template).OfType<Match>();
// Get the parameters { to } and index of any suffixed : formatting code
var paramlist1 = matches.Select(s => new { Parameter = s.Value, FormatIndex = s.Value.IndexOf(':') });
// Extract the key (parameter name) and formatting code from template
var paramlist2 =
paramlist1.Select(s =>
new
{
Key = s.Parameter.Substring(1, s.FormatIndex < 1 ? s.Parameter.Length - 2 : s.FormatIndex - 1),
Format = s.FormatIndex < 1 ? "" : s.Parameter.Substring(s.FormatIndex, s.Parameter.Length - s.FormatIndex - 1),
s.Parameter,
});
// Perform existence checks from both sides
var paramlist2unique = paramlist2.Select(s => s.Key).Distinct();
foreach (var key in parametercollection.Keys)
if (!paramlist2unique.Contains(key))
throw new ArgumentException("Parameter [" + key + "] not found in template");
foreach (var key in paramlist2unique)
if (!parametercollection.ContainsKey(key))
throw new ArgumentException("Template variable {" + key + "} not found in parameter collection");
// Join the template parameters and the values from parametercollection
var paramlist3 =
from p in paramlist2
from v in parametercollection
where p.Key == v.Key
select new
{
//p.Key,
//p.Format,
p.Parameter,
//v.Value,
ValueString = String.Format("{0" + p.Format + "}", v.Value)
};
// Replace the values into the template
var sb = new StringBuilder(template);
foreach (var p in paramlist3)
sb.Replace(p.Parameter, p.ValueString);
return sb.ToString();
}
}
public static class NHibernateSessionExtensions
{
public static void Delete<TEntity>(this ISession session, object id)
{
var queryString = string.Format("delete {0} where id = :id",
typeof(TEntity));
session.CreateQuery(queryString)
.SetParameter("id", id)
.ExecuteUpdate();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment