Skip to content

Commit

Permalink
lots of changes to MSGraph project
Browse files Browse the repository at this point in the history
  • Loading branch information
dgmjr committed Jan 16, 2024
1 parent 649b602 commit 7ffb764
Show file tree
Hide file tree
Showing 65 changed files with 1,377 additions and 488 deletions.
174 changes: 174 additions & 0 deletions src/Bootstrap/AlertTagHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
This TH was written by Rick Strahl
Usage:
<error-display message = "@model.Message"
icon="warning"
header="Error!"
>
</error-display>
Add font-awesome
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
*/

namespace Dgmjr.AspNetCore.TagHelpers.Bootstrap;

/// <summary>
/// Taghelper to display a BootStrap Alert box and FontAwesome icon.
///
/// Message and Header values can be assigned from model values using
/// standard Razor expressions.
///
/// The Helper only displays content when message or header are set
/// otherwise the content is not displayed, so when binding to your
/// model and the model value is empty nothing displays.
/// </summary>
/// <remarks>
/// Requires FontAwesome in addition to bootstrap in order to display icons
/// </remarks>
[HtmlTargetElement("alert")]
public class AlertTagHelper : TagHelper
{
/// <summary>
/// the main message that gets displayed
/// </summary>
[HtmlAttributeName("message")]
public string message { get; set; }

/// <summary>
/// Optional header that is displayed in big text. Use for
/// 'noisy' warnings and stop errors only please :-)
/// The message is displayed below the header.
/// </summary>
[HtmlAttributeName("header")]
public string header { get; set; }

/// <summary>
/// Font-awesome icon name without the fa- prefix.
/// Example: info, warning, lightbulb-o,
/// If none is specified - "warning" is used
/// To force no icon use "none"
/// </summary>
[HtmlAttributeName("icon")]
public string icon { get; set; }

/// <summary>
/// CSS class. Handled here so we can capture the existing
/// class value and append the BootStrap alert class.
/// </summary>
[HtmlAttributeName("class")]
public string cssClass { get; set; }

/// <summary>
/// Optional - specifies the alert class used on the top level
/// window. If not specified uses the same as the icon.
/// Override this if the icon and alert classes are different
/// (often they are not).
/// </summary>
[HtmlAttributeName("alert-class")]
public string alertClass { get; set; }

/// <summary>
/// If true embeds the message text as HTML. Use this
/// flag if you need to display HTML text. If false
/// the text is HtmlEncoded.
/// </summary>
[HtmlAttributeName("message-as-html")]
public bool messageAsHtml { get; set; }

/// <summary>
/// If true embeds the header text as HTML. Use this
/// flag if you need to display raw HTML text. If false
/// the text is HtmlEncoded.
/// </summary>
[HtmlAttributeName("header-as-html")]
public bool headerAsHtml { get; set; }

/// <summary>
/// If true displays a close icon to close the alert.
/// </summary>
[HtmlAttributeName("dismissible")]
public bool dismissible { get; set; }

public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (string.IsNullOrEmpty(message) && string.IsNullOrEmpty(header))
return;

if (string.IsNullOrEmpty(icon))
icon = "warning";
else
icon = icon.Trim();
if (icon == "none")
icon = "";

// assume alertclass to match icon by default
// override it when icon and alert class are diff (ie. info, info-circle)
if (string.IsNullOrEmpty(alertClass))
alertClass = icon;

if (icon == "info")
icon = "info-circle";
if (icon == "danger")
{
icon = "warning";
if (string.IsNullOrEmpty(alertClass))
alertClass = "alert-danger";
}
if (icon == "success")
{
icon = "check";
if (string.IsNullOrEmpty(alertClass))
alertClass = "success";
}

if (icon == "warning" || icon == "error" || icon == "danger")
icon = icon + " text-danger"; // force to error color

if (dismissible && !alertClass.Contains("alert-dismissible"))
alertClass += " alert-dismissible";

string messageText = !messageAsHtml ? System.Net.WebUtility.HtmlEncode(message) : message;
string headerText = !headerAsHtml ? System.Net.WebUtility.HtmlEncode(header) : header;

output.TagName = "div";

// fix up CSS class
if (cssClass != null)
cssClass = cssClass + " alert alert-" + alertClass;
else
cssClass = "alert alert-" + alertClass;
output.Attributes.Add("class", cssClass);
output.Attributes.Add("role", "alert");

StringBuilder sb = new StringBuilder();

if (dismissible)
sb.Append(
"<button type =\"button\" class=\"close\" data-dismiss=\"alert\" aria-label=\"Close\">\r\n"
+ " <span aria-hidden=\"true\">&times;</span>\r\n"
+ "</button>\r\n"
);

if (string.IsNullOrEmpty(header))
{
if (!string.IsNullOrEmpty(icon))
{
sb.Append($"<i class='fa fa-{icon}'></i> ");
}
sb.Append($"{messageText}");
}
else
{
sb.Append($"<h3>");
if (!string.IsNullOrEmpty(icon))
{
sb.Append($"<i class='fa fa-{icon}'></i> ");
}
sb.Append($"{headerText}</h3>\r\n" + "<hr/>\r\n" + $"{messageText}\r\n");
}
output.Content.SetHtmlContent(sb.ToString());
}
}
12 changes: 7 additions & 5 deletions src/Configuration/AssemblyLoadExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ internal static class AssemblyLoadExtensions
{
try
{
return Assembly.LoadFile(filename);
using var asmStream = File.OpenRead(filename);
return Assembly.Load(asmStream.ReadAllBytes());
}
catch (Exception)
catch
{
return null;
}
Expand All @@ -20,7 +21,7 @@ internal static class AssemblyLoadExtensions
{
return Assembly.Load(name);
}
catch (Exception)
catch
{
return null;
}
Expand All @@ -30,8 +31,9 @@ public static IEnumerable<Assembly> GetAssemblies() =>
Directory
.EnumerateFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "*.dll")
.Select(TryLoadAssemblyFromFile)
.WhereNotNull()
.SelectMany(assembly => assembly.GetReferencedAssemblies().Select(TryLoadAssembly))
.Distinct()
// .Distinct()
.WhereNotNull()
.ToList();

Expand All @@ -41,7 +43,7 @@ public static IEnumerable<type> TryGetTypes(this Assembly asm)
{
return asm.GetTypes();
}
catch (Exception)
catch
{
return Enumerable.Empty<type>();
}
Expand Down
14 changes: 9 additions & 5 deletions src/Configuration/AutoConfigureIApplicationBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@ public static class AutoConfigureIApplicationBuilderExtensions
{
public static IApplicationBuilder AutoConfigure(this IApplicationBuilder builder)
{
var configurators = AssemblyLoadExtensions
.GetTypesAssignableTo<IConfigureIApplicationBuilder>()
.Select(Activator.CreateInstance)
.OfType<IConfigureIApplicationBuilder>()
var configurators = builder.ApplicationServices
.GetServices<IConfigureIApplicationBuilder>()
.OrderBy(configurator => configurator.Order)
.ToList();

Console.WriteLine(
$"Configuring IApplicationBuilder with the following configurators: {Join(", ", configurators.Select(configurator => configurator.GetType().Name))}."
);

foreach (var configurator in configurators)
{
Console.WriteLine($"Configuring {configurator.GetType().Name}.");
Console.WriteLine(
$"Configuring IApplicationBuilder with {configurator.GetType().Name}."
);
configurator.Configure(builder);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace Microsoft.Extensions.DependencyInjection;

using Dgmjr.Configuration.Extensions;

using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

Expand All @@ -11,16 +12,41 @@ public static class AutoConfigureIApplicationHostBuilderExtensions
{
public static IHostApplicationBuilder AutoConfigure(this IHostApplicationBuilder builder)
{
var configurators = AssemblyLoadExtensions
.GetTypesAssignableTo<IConfigureIHostApplicationBuilder>()
.Select(Activator.CreateInstance)
.OfType<IConfigureIHostApplicationBuilder>()
var hostBuilderConfiguratorTypes = AssemblyLoadExtensions
.GetTypesAssignableTo<IConfigureIHostApplicationBuilder>();

var appBuilderConfiguratorTypes = AssemblyLoadExtensions
.GetTypesAssignableTo<IConfigureIApplicationBuilder>();

var services = new ServiceCollection();
foreach(var serviceDescriptor in builder.Services)
{
services.Add(serviceDescriptor);
}

foreach (var configuratorType in hostBuilderConfiguratorTypes)
{
services.TryAddEnumerable(new ServiceDescriptor(typeof(IConfigureIHostApplicationBuilder), configuratorType, ServiceLifetime.Singleton));
builder.Services.TryAddEnumerable(new ServiceDescriptor(typeof(IConfigureIHostApplicationBuilder), configuratorType, ServiceLifetime.Singleton));
}

foreach(var configuratorType in appBuilderConfiguratorTypes)
{
services.TryAddEnumerable(new ServiceDescriptor(typeof(IConfigureIApplicationBuilder), configuratorType, ServiceLifetime.Singleton));
builder.Services.TryAddEnumerable(new ServiceDescriptor(typeof(IConfigureIApplicationBuilder), configuratorType, ServiceLifetime.Singleton));
}

var configurators = services.BuildServiceProvider().GetServices<IConfigureIHostApplicationBuilder>()
.OrderBy(configurator => configurator.Order)
.ToList();

Console.WriteLine(
$"Configuring IHostApplicationBuilder with the following configurators: {Join(", ", configurators.Select(configurator => configurator.GetType().Name))}."
);

foreach (var configurator in configurators)
{
Console.WriteLine($"Configuring {configurator.GetType().Name}.");
Console.WriteLine($"Configuring IHostApplicationBuilder with {configurator.GetType().Name}.");
configurator.Configure(builder);
}

Expand Down
10 changes: 5 additions & 5 deletions src/Configuration/ConfigurationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ namespace Dgmjr.Extensions.Configuration;

public static class ConfigurationExtensions
{
public static string ToJson(this IConfiguration config) =>
JsonSerializer.Serialize(config.AsEnumerable(), new Jso
public static string ToJson(this IConfiguration config)
{
return JsonSerializer.Serialize(config, new Jso
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
Converters = { new ConfigurationJsonConverter() }
});
}
}
28 changes: 28 additions & 0 deletions src/Configuration/ConfigurationJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Dgmjr.Extensions.Configuration;

public class ConfigurationJsonConverter : JsonConverter<IConfiguration>
{
public override IConfiguration? Read(ref Utf8JsonReader reader, type typeToConvert, Jso options)
{
using var jsonStream = new MemoryStream(reader.ValueSpan.ToArray());
return new ConfigurationBuilder().AddJsonStream(jsonStream).Build();
}

public override void Write(Utf8JsonWriter writer, IConfiguration value, Jso options)
{
writer.WriteStartObject();
foreach (var section in value.GetChildren())
{
writer.WritePropertyName(section.Key);
if (section.GetChildren().Any())
{
Write(writer, section, options);
}
else
{
writer.WriteStringValue(section.Value);
}
}
writer.WriteEndObject();
}
}
4 changes: 4 additions & 0 deletions src/Configuration/Dgmjr.Configuration.Extensions.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
<Content Include="$(MSBuildProjectDirectory)appsettings/*.json" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />
<Content Include="$(MSBuildProjectDirectory)settings/*.json" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />
</ItemGroup>
<ItemGroup>
<Using Include="Dgmjr.Configuration.Extensions" />
<Using Include="Dgmjr.Extensions.Configuration" />
</ItemGroup>
</Project>
42 changes: 42 additions & 0 deletions src/Configuration/Dgmjr.Configuration.Extensions.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Microsoft Visual Studio Solution File, Format Version 12.00
#
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}"
ProjectSection(SolutionItems) = preProject
..\..\Directory.Build.props = ..\..\Directory.Build.props
..\..\..\..\Directory.Build.targets = ..\..\..\..\Directory.Build.targets
..\..\..\..\global.json = ..\..\..\..\global.json
..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\Packages\Versions.Local.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dgmjr.Configuration.Extensions", "Dgmjr.Configuration.Extensions.csproj", "{C10E1908-6EE4-4069-ABBB-33427AC25720}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Local|Any CPU = Local|Any CPU
Debug|Any CPU = Debug|Any CPU
Testing|Any CPU = Testing|Any CPU
Staging|Any CPU = Staging|Any CPU
Production|Any CPU = Production|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Local|Any CPU.ActiveCfg = Local|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Local|Any CPU.Build.0 = Local|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Testing|Any CPU.ActiveCfg = Testing|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Testing|Any CPU.Build.0 = Testing|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Staging|Any CPU.ActiveCfg = Staging|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Staging|Any CPU.Build.0 = Staging|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Production|Any CPU.ActiveCfg = Local|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Production|Any CPU.Build.0 = Local|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C10E1908-6EE4-4069-ABBB-33427AC25720}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E8FAF0BF-8DF5-4922-A103-786B5533648B}
EndGlobalSection
EndGlobal
Loading

0 comments on commit 7ffb764

Please sign in to comment.