Skip to content

Commit 5c1b382

Browse files
committed
Logic and implementation for members and depedency injection.
1 parent 19c147e commit 5c1b382

28 files changed

+1652
-34
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Grpc/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

CDF-Solution/CommonDeliveryFramework.Net.Aspnet/ControllerBaseExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public static ProblemObjectResult CreateProblemResult(this ControllerBase source
6969
private static ProblemObjectResult CreateGenericInternalServerErrorProblemResult()
7070
{
7171
var problem = new ProblemDetails
72-
{ Type = "https://httpstatuses.com/500", Status = 500, Title = "Internal Server Error", Detail = "An internal error has occured and the operation could not complete." };
72+
{ Type = "https://httpstatuses.com/500", Status = 500, Title = "Internal Server Error", Detail = "An internal error has occurred and the operation could not complete." };
7373

7474
return new ProblemObjectResult(problem);
7575
}

CDF-Solution/CommonDeliveryFramework.Net.Aspnet/ManagedExceptionExtensions.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static class ManagedExceptionExtensions
1111
/// Extension method that generates problem details for the exception.
1212
/// </summary>
1313
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
14-
/// <param name="controller">The base controller the exception occured in. </param>
14+
/// <param name="controller">The base controller the exception occurred in. </param>
1515
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/403 </param>
1616
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 403.</param>
1717
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to Forbidden.</param>
@@ -27,7 +27,7 @@ public static ProblemDetails GetProblemDetails(this ExternalAccessException sour
2727
/// Extension method that generates problem details for the exception.
2828
/// </summary>
2929
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
30-
/// <param name="controller">The base controller the exception occured in. </param>
30+
/// <param name="controller">The base controller the exception occurred in. </param>
3131
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/504 </param>
3232
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 504.</param>
3333
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to Gateway Timeout.</param>
@@ -43,7 +43,7 @@ public static ProblemDetails GetProblemDetails(this CommunicationException sourc
4343
/// Extension method that generates problem details for the exception.
4444
/// </summary>
4545
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
46-
/// <param name="controller">The base controller the exception occured in. </param>
46+
/// <param name="controller">The base controller the exception occurred in. </param>
4747
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/500 </param>
4848
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 500.</param>
4949
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to Internal Server Error.</param>
@@ -59,7 +59,7 @@ public static ProblemDetails GetProblemDetails(this ConfigurationException sourc
5959
/// Extension method that generates problem details for the exception.
6060
/// </summary>
6161
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
62-
/// <param name="controller">The base controller the exception occured in. </param>
62+
/// <param name="controller">The base controller the exception occurred in. </param>
6363
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/500 </param>
6464
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 500.</param>
6565
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to Internal Server Error.</param>
@@ -75,7 +75,7 @@ public static ProblemDetails GetProblemDetails(this DataException source,
7575
/// Extension method that generates problem details for the exception.
7676
/// </summary>
7777
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
78-
/// <param name="controller">The base controller the exception occured in. </param>
78+
/// <param name="controller">The base controller the exception occurred in. </param>
7979
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/400 </param>
8080
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 400.</param>
8181
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to Bad Request.</param>
@@ -91,7 +91,7 @@ public static ProblemDetails GetProblemDetails(this ValidationException source,
9191
/// Extension method that generates problem details for the exception.
9292
/// </summary>
9393
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
94-
/// <param name="controller">The base controller the exception occured in. </param>
94+
/// <param name="controller">The base controller the exception occurred in. </param>
9595
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/500 </param>
9696
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 500.</param>
9797
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to Internal Server Error.</param>
@@ -107,7 +107,7 @@ public static ProblemDetails GetProblemDetails(this LogicException source,
107107
/// Extension method that generates problem details for the exception.
108108
/// </summary>
109109
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
110-
/// <param name="controller">The base controller the exception occured in. </param>
110+
/// <param name="controller">The base controller the exception occurred in. </param>
111111
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/500 </param>
112112
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 500.</param>
113113
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to Internal Server Error.</param>
@@ -123,7 +123,7 @@ public static ProblemDetails GetProblemDetails(this ManagedException source,
123123
/// Extension method that generates problem details for the exception.
124124
/// </summary>
125125
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
126-
/// <param name="controller">The base controller the exception occured in. </param>
126+
/// <param name="controller">The base controller the exception occurred in. </param>
127127
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/401 </param>
128128
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 401.</param>
129129
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to UnAuthorized.</param>
@@ -139,7 +139,7 @@ public static ProblemDetails GetProblemDetails(this SecurityException source,
139139
/// Extension method that generates problem details for the exception.
140140
/// </summary>
141141
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
142-
/// <param name="controller">The base controller the exception occured in. </param>
142+
/// <param name="controller">The base controller the exception occurred in. </param>
143143
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/504 </param>
144144
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 504.</param>
145145
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to GatewayTimeout.</param>
@@ -155,7 +155,7 @@ public static ProblemDetails GetProblemDetails(this TimeoutException source,
155155
/// Extension method that generates problem details for the exception.
156156
/// </summary>
157157
/// <param name="source">The exception to map to a <see cref="ProblemDetails"/></param>
158-
/// <param name="controller">The base controller the exception occured in. </param>
158+
/// <param name="controller">The base controller the exception occurred in. </param>
159159
/// <param name="type">Optional parameter that sets the URL for the human readable explanation for the status code. Default value is set to https://httpstatuses.com/500 </param>
160160
/// <param name="status">Optional parameter that sets the return status code for the problem. Default value is set to 500.</param>
161161
/// <param name="title">Optional parameter that sets the title for the problem. Default value is set to Internal Server Error.</param>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+

2+
namespace CommonDeliveryFramework.Net.Automation.Common
3+
{
4+
/// <summary>
5+
/// Data class that contain a number of constants that are used throughout automation with asp.net core.
6+
/// </summary>
7+
public static class AspNetCoreConstants
8+
{
9+
/// <summary>
10+
/// The name of the filed that holds the logger
11+
/// </summary>
12+
public const string FieldNameLogger = "_logger";
13+
14+
/// <summary>
15+
/// The full name of the library for logging.
16+
/// </summary>
17+
public const string MicrosoftExtensionLibraryForLoggingName = "Microsoft.Extensions.Logging.Abstractions";
18+
19+
/// <summary>
20+
/// Library name for the Microsoft Logger abstractions library.
21+
/// </summary>
22+
public const string MicrosoftLoggerLibraryName = "Microsoft.Extensions.Logging.Abstractions";
23+
24+
/// <summary>
25+
/// The default namespace for the Microsoft extensions logger implementation
26+
/// </summary>
27+
public const string MicrosoftLoggerNamespace = "Microsoft.Extensions.Logging";
28+
29+
/// <summary>
30+
/// The name of the interface for the Microsoft extensions logger.
31+
/// </summary>
32+
public const string MicrosoftLoggerInterfaceName = "ILogger";
33+
34+
/// <summary>
35+
/// The fully qualified name of the a aspnet core controller.
36+
/// </summary>
37+
public const string ControllerBaseName = "Microsoft.AspNetCore.Mvc.ControllerBase";
38+
39+
/// <summary>
40+
/// The full namespace for the mvc namespace.
41+
/// </summary>
42+
public const string MvcNamespace = "Microsoft.AspNetCore.Mvc";
43+
44+
/// <summary>
45+
/// Name for the abstract classes that support action result.
46+
/// </summary>
47+
public const string ActionResultClassName = "ActionResult";
48+
49+
/// <summary>
50+
/// Name of the interface for action results.
51+
/// </summary>
52+
public const string ActionResultInterfaceName = "IActionResult";
53+
54+
/// <summary>
55+
/// Namespace for tasks
56+
/// </summary>
57+
public const string SystemThreadingTasksNamespace = "System.Threading.Tasks";
58+
59+
/// <summary>
60+
/// Class name for the Task class.
61+
/// </summary>
62+
public const string TaskClassName = "Task";
63+
}
64+
}

CDF-Solution/CommonDeliveryFramework.Net.Automation.Common/CommonDeliveryFramework.Net.Automation.Common.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
<Reference Include="WindowsBase" />
5151
</ItemGroup>
5252
<ItemGroup>
53+
<Compile Include="AspNetCoreConstants.cs" />
54+
<Compile Include="CsClassExtensions.cs" />
55+
<Compile Include="CsClassMemberExtensions.cs" />
56+
<Compile Include="DependencyInjectionExtensions.cs" />
57+
<Compile Include="GrpcConstants.cs" />
5358
<Compile Include="Properties\AssemblyInfo.cs" />
5459
</ItemGroup>
5560
<ItemGroup />
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
using System;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using CodeFactory;
5+
using CodeFactory.DotNet.CSharp;
6+
7+
namespace CommonDeliveryFramework.Net.Automation.Common
8+
{
9+
/// <summary>
10+
/// Extensions class that provides common automation tasks rolled up under standard extension methods that support the <see cref="CsClass"/> model.
11+
/// </summary>
12+
public static class CsClassExtensions
13+
{
14+
/// <summary>
15+
/// Extension method that determines if the class implements a logger field that supports extensions logging from Microsoft.
16+
/// </summary>
17+
/// <param name="source">Class model to evaluate.</param>
18+
/// <param name="loggerName">The name of the logger field.</param>
19+
/// <returns>Boolean flag if the field was found or not.</returns>
20+
public static bool HasMicrosoftExtensionsLoggerField(this CsClass source, string loggerName)
21+
{
22+
//Bounds check to determine if a class model was provided.
23+
if (source == null) return false;
24+
25+
//Bounds check to confirm a field name was provided for the logger.
26+
if (String.IsNullOrEmpty(loggerName)) return false;
27+
28+
//Bounds check to confirm the target class has fields.
29+
if (!source.Fields.Any()) return false;
30+
31+
//Looking up the field definition by the variable name of the logger.
32+
var field = source.Fields.FirstOrDefault(f => f.Name == loggerName);
33+
34+
//If the logger was not found return false.
35+
if (field == null) return false;
36+
37+
//Confirming the fields data type is under the logger namespace.
38+
if (field.DataType.Namespace != AspNetCoreConstants.MicrosoftLoggerNamespace) return false;
39+
40+
//Confirming the field type is the ILogger interface
41+
// ReSharper disable once ConvertIfStatementToReturnStatement
42+
if (field.DataType.Name != AspNetCoreConstants.MicrosoftLoggerInterfaceName) return false;
43+
44+
return true;
45+
}
46+
47+
/// <summary>
48+
/// Extension method that determines if the logger field is implemented in the class. If it exists will return the provided source. Otherwise will add the logging namespace and the logger field.
49+
/// </summary>
50+
/// <param name="source">Source class to check for the logger field.</param>
51+
/// <param name="loggerName">The name of the logger field to check for.</param>
52+
/// <param name="parentSourceCode">The source code the class was loaded from.</param>
53+
/// <returns>The existing source code if the field is found, or the updated source code with the logging field added.</returns>
54+
public static async Task<CsSource> AddMicrosoftExtensionsLoggerFieldAsync(this CsClass source, string loggerName,
55+
CsSource parentSourceCode)
56+
{
57+
//Bounds checking
58+
if (source == null) return parentSourceCode;
59+
if (String.IsNullOrEmpty(loggerName)) return parentSourceCode;
60+
61+
//Checking to see if the logger field already exists. If it does just return the parent source code.
62+
if (source.HasMicrosoftExtensionsLoggerField(loggerName)) return parentSourceCode;
63+
64+
//Adding the logging namespace
65+
var currentSource = await parentSourceCode.AddUsingStatementAsync(AspNetCoreConstants.MicrosoftLoggerNamespace);
66+
67+
var currentClass = currentSource.GetModel(source.LookupPath) as CsClass;
68+
69+
if (currentClass == null) throw new CodeFactoryException("Cannot load class data to add the logger field.");
70+
71+
CodeFactory.SourceFormatter fieldSource = new CodeFactory.SourceFormatter();
72+
73+
fieldSource.AppendCodeLine(2, "/// <summary>");
74+
fieldSource.AppendCodeLine(2, "/// Logger for all logging interactions in the class.");
75+
fieldSource.AppendCodeLine(2, "/// </summary>");
76+
fieldSource.AppendCodeLine(2, $"private readonly {AspNetCoreConstants.MicrosoftLoggerInterfaceName} {loggerName};");
77+
fieldSource.AppendCodeLine(0);
78+
79+
currentSource = await currentClass.AddToBeginningAsync(fieldSource.ReturnSource());
80+
81+
return currentSource;
82+
83+
}
84+
85+
/// <summary>
86+
/// Helper method that confirms the class model base implementation is a controller.
87+
/// </summary>
88+
/// <param name="classModel">The class model to confirm does not implement a base class.</param>
89+
/// <returns>True if a controller, false if not.</returns>
90+
public static bool IsController(this CsClass classModel)
91+
{
92+
var baseClass = classModel?.BaseClass;
93+
if (baseClass == null) return false;
94+
95+
var baseClassName = $"{baseClass.Namespace}.{baseClass.Name}";
96+
97+
if (baseClassName == AspNetCoreConstants.ControllerBaseName) return true;
98+
99+
bool isBaseClass = false;
100+
if (baseClass.BaseClass != null) isBaseClass = IsController(baseClass);
101+
return isBaseClass;
102+
}
103+
104+
/// <summary>
105+
/// Helper method that confirms the class model is not a Grpc service implementation.
106+
/// </summary>
107+
/// <param name="classModel">The class model to check if it is a Grpc Service.</param>
108+
/// <returns>True if a Grpc service, false if not.</returns>
109+
public static bool IsGrpcService(this CsClass classModel)
110+
{
111+
var baseClass = classModel?.BaseClass;
112+
113+
if (baseClass == null) return false;
114+
115+
if (!baseClass.HasAttributes) return false;
116+
117+
if (baseClass.Attributes.Any(b =>
118+
b.Type.Namespace == GrpcConstants.GrpcCoreNamespace & b.Type.Name == GrpcConstants.BindServiceAttributeName )) return true;
119+
120+
bool isBaseClass = false;
121+
if (baseClass.BaseClass != null) isBaseClass = baseClass.BaseClass.IsGrpcService();
122+
return isBaseClass;
123+
}
124+
125+
/// <summary>
126+
/// Helper method that confirms the class model is not a razor component.
127+
/// </summary>
128+
/// <param name="classModel">Source class model to check.</param>
129+
/// <returns>True if a component, false if not.</returns>
130+
public static bool IsRazorComponent(this CsClass classModel)
131+
{
132+
if (classModel.SourceDocument.EndsWith("razor", StringComparison.InvariantCultureIgnoreCase)) return true;
133+
return classModel.SourceDocument.EndsWith("razor.cs", StringComparison.InvariantCultureIgnoreCase);
134+
}
135+
}
136+
}

0 commit comments

Comments
 (0)