Collection of extensions and code fragments.
Last active
April 8, 2019 13:47
-
-
Save llaughlin/6112dde3b6a6b4ba8545faf960923b95 to your computer and use it in GitHub Desktop.
dotnet Extensions
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 Log4Net2Serilog | |
{ | |
/// <summary> | |
/// Configures log4net to log to Serilog. | |
/// </summary> | |
/// <param name="logger">The serilog logger (if left null Log.Logger will be used).</param> | |
public static void Configure(ILogger logger = null) | |
{ | |
var serilogAppender = new SerilogAppender(logger); | |
serilogAppender.ActivateOptions(); | |
var loggerRepository = (Hierarchy)LogManager.GetRepository(Assembly.GetCallingAssembly()); | |
if (loggerRepository.Root.GetAppender(serilogAppender.Name) == null) | |
{ | |
loggerRepository.Root.AddAppender(serilogAppender); | |
} | |
loggerRepository.Configured = true; | |
} | |
private class SerilogAppender : AppenderSkeleton | |
{ | |
private static readonly Func<SystemStringFormat, string> FormatGetter; | |
private static readonly Func<SystemStringFormat, object[]> ArgumentsGetter; | |
private readonly ILogger _Logger; | |
static SerilogAppender() | |
{ | |
FormatGetter = GetFieldAccessor<SystemStringFormat, string>("m_format"); | |
ArgumentsGetter = GetFieldAccessor<SystemStringFormat, object[]>("m_args"); | |
} | |
public SerilogAppender(ILogger logger = null) => _Logger = logger; | |
protected override void Append(LoggingEvent loggingEvent) | |
{ | |
var source = loggingEvent.LoggerName; | |
var serilogLevel = ConvertLevel(loggingEvent.Level); | |
string template; | |
object[] parameters = null; | |
if (loggingEvent.MessageObject is SystemStringFormat systemStringFormat) | |
{ | |
template = FormatGetter(systemStringFormat); | |
parameters = ArgumentsGetter(systemStringFormat); | |
} | |
else | |
{ | |
template = loggingEvent.MessageObject?.ToString(); | |
} | |
var logger = (_Logger ?? Log.Logger).ForContext(Constants.SourceContextPropertyName, source); | |
logger.Write(serilogLevel, loggingEvent.ExceptionObject, template, parameters); | |
} | |
private static LogEventLevel ConvertLevel(Level log4NetLevel) | |
{ | |
if (log4NetLevel == Level.Verbose) | |
{ | |
return LogEventLevel.Verbose; | |
} | |
if (log4NetLevel == Level.Debug) | |
{ | |
return LogEventLevel.Debug; | |
} | |
if (log4NetLevel == Level.Info) | |
{ | |
return LogEventLevel.Information; | |
} | |
if (log4NetLevel == Level.Warn) | |
{ | |
return LogEventLevel.Warning; | |
} | |
if (log4NetLevel == Level.Error) | |
{ | |
return LogEventLevel.Error; | |
} | |
if (log4NetLevel == Level.Fatal) | |
{ | |
return LogEventLevel.Fatal; | |
} | |
SelfLog.WriteLine("Unexpected log4net logging level ({0}) logging as Information", log4NetLevel.DisplayName); | |
return LogEventLevel.Information; | |
} | |
//taken from http://rogeralsing.com/2008/02/26/linq-expressions-access-private-fields/ | |
public static Func<T, TField> GetFieldAccessor<T, TField>(string fieldName) | |
{ | |
var param = Expression.Parameter(typeof(T), "arg"); | |
var member = Expression.Field(param, fieldName); | |
var lambda = Expression.Lambda(typeof(Func<T, TField>), member, param); | |
var compiled = (Func<T, TField>)lambda.Compile(); | |
return compiled; | |
} | |
} | |
} |
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 MemoryExtensions | |
{ | |
private static readonly List<string> ByteNames = new List<string> {"Bytes", "KB", "MB", "GB"}; | |
public static string ToFileSize(this int source) => Convert.ToInt64(source).ToFileSize(); | |
public static string ToFileSize(this long source) | |
{ | |
const int byteConversion = 1024; | |
var bytes = Math.Abs(Convert.ToDouble(source)); | |
var prefix = source < 0 ? "-" : ""; | |
for (var i = 4; i >= 0; i--) | |
{ | |
var converted = Math.Pow(byteConversion, i); | |
if (bytes >= converted) | |
{ | |
return $"{prefix}{Math.Round(bytes / converted, 2)} {ByteNames[i]}"; | |
} | |
} | |
return "Unknown"; | |
} | |
} |
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 ObservableExtensions | |
{ | |
public static IObservable<IList<T>> SlidingWindow<T>(this IObservable<T> source, int windowSize) | |
{ | |
var publishedSource = source.Publish().RefCount(); | |
return Enumerable.Range(0, windowSize) | |
.Select(skip => publishedSource.Skip(skip)).Zip(); | |
} | |
} |
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 SlidingWindowExtensions | |
{ | |
public static IObservable<IList<T>> SlidingWindow<T>(this IObservable<T> source, int windowSize) | |
{ | |
var publishedSource = source.Publish().RefCount(); | |
return Enumerable.Range(0, windowSize) | |
.Select(skip => publishedSource.Skip(skip)).Zip(); | |
} | |
public static IEnumerable<IList<T>> SlidingWindow<T>(this IEnumerable<T> source, int windowSize) | |
{ | |
var window = new List<T>(windowSize); | |
foreach(var line in source) | |
{ | |
if(window.Count == windowSize) | |
{ | |
window.RemoveAt(0); | |
} | |
window.Add(line); | |
if(window.Count == windowSize) | |
{ | |
yield return window; | |
} | |
} | |
//return Enumerable.Range(0, source.Count()).Select(i => source.Skip(i).Take(windowSize).ToList()); | |
} | |
} |
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
<Target Name="NugetRestore" BeforeTargets="Build" Condition=" !Exists('obj\project.assets.json') "> | |
<Message Importance="high" Text="Restoring nuget packages..." /> | |
<Exec Command="nuget restore" ContinueOnError="true"> | |
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" /> | |
</Exec> | |
<Error Condition="'$(ErrorCode)' != '0'" Text="nuget restore failed" /> | |
</Target> | |
<Target Name="YarnRestore" BeforeTargets="Build"> | |
<Exec Command="yarn --version" ContinueOnError="true"> | |
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" /> | |
</Exec> | |
<Error Condition="'$(ErrorCode)' != '0'" Text="yarn is required to build and run this project." /> | |
<Message Importance="high" Text="Restoring yarn packages..." /> | |
<Exec Command="yarn" ContinueOnError="true"> | |
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" /> | |
</Exec> | |
<Error Condition="'$(ErrorCode)' != '0'" Text="error running yarn" /> | |
</Target> | |
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' "> | |
<!-- Ensure Node.js is installed --> | |
<Exec Command="node --version" ContinueOnError="true"> | |
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" /> | |
</Exec> | |
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." /> | |
<!-- In development, the dist files won't exist on the first run or when cloning to | |
a different machine, so rebuild them if not already present. --> | |
<Message Importance="high" Text="Performing first-run Webpack build..." /> | |
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.js" /> | |
<Exec Command="node node_modules/webpack/bin/webpack.js" /> | |
</Target> | |
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish"> | |
<!-- As part of publishing, ensure the JS resources are freshly built in production mode --> | |
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.js --env.prod" /> | |
<Exec Command="node node_modules/webpack/bin/webpack.js --env.prod" /> | |
<!-- Include the newly-built files in the publish output --> | |
<ItemGroup> | |
<DistFiles Include="wwwroot\dist\**" /> | |
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)"> | |
<RelativePath>%(DistFiles.Identity)</RelativePath> | |
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> | |
</ResolvedFileToPublish> | |
</ItemGroup> | |
</Target> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment