Last active
January 14, 2019 10:42
-
-
Save oguzhaneren/06bbfb0913c205b55c885584720a6f90 to your computer and use it in GitHub Desktop.
C# Extensions & Helpers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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())); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
-- NamedStringFormatExtension.cs
http://phejndorf.wordpress.com/2011/02/26/formatting-a-string-with-named-parameters/
http://snipplr.com/view/28624/
http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx/