How to get json settings in .net core 3.1 console app - console-application

I am following the example shown here: https://stackoverflow.com/a/65111169
However, I can't seem to get it to work because I get an error message: IConfiguration does not contain a definition for Get....
I have imported Microsoft.Extensions.Configuration and Microsoft.Extensions.Configuration.Jason, both version 3.1.32. Why doesn't it work? I also tried nesting my json file inside a Settings property so that I could try this: var myFirstClass = config.GetSection("Settings").GetValue<MyFirstClass>("Settings","myFirstClass"); When I use this GetValue syntax I have no errors, but my variable is null.
static void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false);
IConfiguration config = builder.Build();
var myFirstClass = config.GetSection("myFirstClass").Get<MyFirstClass>();
}
My appsettings.json
{
"MyFirstClass": {
"Option1": "some string value",
"Option2": 42
},
"MySecondClass": {
"SettingOne": "some string value",
"SettingTwo": 42
}
}

Related

AEM Mocks: Cannot Inject Config

I am using AEM Mocks to test a custom servlet that uses a configuration, as such:
#Activate
void activate(final Config config) { ... }
I am following the approach described here and here to register and inject the service together with a HashMap, as such:
private static Map<String, Object> myHashMap = new HashMap<>();
...
myHashMap.put("a", "b");
myHashMap.put("c", "d");
...
servlet = context.registerInjectActivateService(new MyServlet(), myHashMap);
However, this approach doesn't work. The config object passed above, inside the activate function, is corrupted. For every key-value pair above, it sets null as the value. So instead of:
a -> b
c -> d
It sets:
a -> null
c -> null
Inside the HashMap. Can anyone please help? Thanks!
P.S. I should add that I am using version 2.3.0 of AEM Mocks since the recent versions cause an issue with an older artifact. For more info on that, see here.
I tested it, and it works with version 2.3.0 too. Could you check the following example? After that, it is probably a maven issue. Then we would need more information.
Here is my test servlet:
#Component(service = Servlet.class,
property = {
SLING_SERVLET_PATHS + "=/bin/servlet/test",
SLING_SERVLET_METHODS + "=GET",
SLING_SERVLET_EXTENSIONS + "=text"
})
#Designate(ocd = TestServlet.Config.class)
public class TestServlet extends SlingSafeMethodsServlet {
#ObjectClassDefinition
public #interface Config {
#AttributeDefinition(
name = "Name",
description = "Name used in the hello world text"
)
String name() default "Alex";
#AttributeDefinition(
name = "Greeting",
description = "Greeting - Morning, to demonstrate the dot-replacement"
)
String greeting_morning() default "Good Morning";
}
private Config config;
#Override
protected void doGet(#Nonnull SlingHttpServletRequest request, #Nonnull SlingHttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().println(this.getGreeting());
}
public String getGreeting() {
return config.greeting_morning() + ", " + config.name();
}
#Activate
void activate(final Config config) {
this.config = config;
}
}
Here is a JUnit 4 test:
public class TestServletTest {
#Rule
public final AemContext context = new AemContext();
#Test
public void testWithoutConfig() {
final TestServlet testServlet = context.registerInjectActivateService(new TestServlet());
assertEquals("Good Morning, Alex", testServlet.getGreeting());
}
#Test
public void testWithConfig() {
final Map<String, Object> properties = new HashMap<>();
properties.put("name", "Berndt");
properties.put("greeting.morning", "Keep sleeping");
final TestServlet testServlet = context.registerInjectActivateService(new TestServlet(), properties);
assertEquals("Keep sleeping, Berndt", testServlet.getGreeting());
}
}

Compile to module with Roslyn

I need to compile any C# or VB.NET project to .NetModule. I have following sample code which emits DLLs, Need some help to modify following to get .NetModules out from .csproj
Thanks in advance.
// Required Microsoft.CodeAnalysis 1.3.0
class Program
{
static void Main(string[] args)
{
try
{
//Please copy provide a path to a .csproj
CompileProject(#"C:\WebGoat\WebGoat.NET.csproj", #"C:\tempout").Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
async static Task<string> CompileProject(string projectFilePath, string outputFolderPath)
{
using (var workspace = MSBuildWorkspace.Create())
{
var project = workspace.OpenProjectAsync(projectFilePath).Result;
await Emit(project, outputFolderPath);
return Path.GetFileName(project.OutputFilePath);
}
}
async static Task Emit(Project project, string outputFolderPath)
{
Directory.CreateDirectory(outputFolderPath);
var compilation = await project.GetCompilationAsync();
var outputFilePath = Path.Combine(outputFolderPath, Path.GetFileName(project.OutputFilePath));
var pdbFilePath = Path.ChangeExtension(outputFilePath, "pdb");
var compilationStatus = compilation.Emit(outputFilePath, pdbPath: pdbFilePath);
if (!compilationStatus.Success)
{
Console.WriteLine("Failed.");
}
else
{
Console.WriteLine("Pass.");
}
}
I believe you're looking for CompilationOptions.OutputKind and specifically OutputKind.NetModule.
Something similar to the following should work:
var project = workspace.OpenProjectAsync(projectFilePath).Result;
var options = project.CompilationOptions;
var netModuleOptions = options.WithOutputKind(OutputKind.NetModule);
var projectWithOptions = project.WithCompilationOptions(netModuleOptions);
Now you should be able to get a compilation and emit it as you normally would.
Following fixed the issue
var project = workspace.OpenProjectAsync(projectFilePath).Result;
var options = project.CompilationOptions;
options = options.WithOutputKind(OutputKind.NetModule).WithPlatform(Platform.AnyCpu);
project = project.WithCompilationOptions(options);
var moduleCompilation = await project.GetCompilationAsync();

How to access IConfiguration in test script

I have a controller in my MVC asp.net core app.
Inside this app I am using DP to access the appsettings.json file:
public class APIServicesController : Controller
{
IConfiguration _iconfiguration;
public APIServicesController(IConfiguration iconfiguration)
{
_iconfiguration = iconfiguration;
}
public IActionResult Index()
{
var Key = _iconfiguration.GetSection("EMAIL_API").GetSection("Key").Value;
var uri = _iconfiguration.GetSection("EMAIL_API").GetSection("uri").Value;
var emailAddress = "an email address";
var res = _api.ValidateEmail(emailAddress, Key , uri );
return View();
}
}
Now I am trying to create a test script for this. How do I access/use the IConfiguration from my test script?
[TestMethod]
public async System.Threading.Tasks.Task ValidateEmail()
{
var emailAddress = "an email address";
var res = await _api.ValidateEmail(emailAddress, key, uri);
Assert.AreEqual(res, true);
}
I did something like this in an integration test class:
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
var config = builder.Build();
Add this nuget package: Microsoft.Extensions.Configuration.Json
Now that you have the config file, you can get what you need:
config.GetSection("whateverSection");
An easy way to build the memory completely within the test:
IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection()
.Build();
configuration["SomeKey"] = "some value";

Roslyn VSIX Does Not Underline Document After reporting

I've written an analyzer, and verified it was working.
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class ConstDiagnosticAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "LocalizationTool";
private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.ConstAnalyzerTitle), Resources.ResourceManager, typeof(Resources));
private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.ConstAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.ConstAnalyzerDescription), Resources.ResourceManager, typeof(Resources));
private const string Category = "Naming";
private static ResourceLocalizationRule localizationRule = new ResourceLocalizationRule();
private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeConstDeclaration, SyntaxKind.FieldDeclaration);
}
public static void AnalyzeConstDeclaration(SyntaxNodeAnalysisContext context)
{
var fieldDeclaration = (FieldDeclarationSyntax)context.Node;
if (false == IsValidConstDeclaration(context, fieldDeclaration))
{
return;
}
var firstVariable = fieldDeclaration.Declaration.Variables.FirstOrDefault();
var firstSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariable);
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation(), firstSymbol.Name));
}
private static bool IsValidConstDeclaration(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclaration)
{
if (false == fieldDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword))
{
return false;
}
return true;
}
}
I've written a simple class which reports for analyzing const. This was underlining appropriately at one point. It's analyzer seems to be triggering because the resolution appears under Quick Actions, However the underlining is not working as seem in the image below
Adding Error List
As you can see there are warnings that have no messages. Why are there no messages when I'm clearly appending a message
It turns out this was cause by an overlooked warning. My resources were having a missing manifest exception.
So when they were trying to grab out the resource file descriptions etc, they were in-accessible. So the analyzer would trigger but it would have no messages.
I ended up using this solution to fix the missing manifest

Unity PerRequestLifetimeManager UnitTest

I have following Unity configuration:
public static void RegisterTypes(IUnityContainer container)
{
...
container.RegisterType<IRootDatabaseContext, RootEntities>(new PerRequestLifetimeManager());
...
}
And everything works fine. But when I also want to test this method:
[TestMethod]
public void AssertUnityConfigAreValid()
{
using (var container = new UnityContainer())
{
UnityConfig.RegisterTypes(container);
foreach (var registration in container.Registrations)
{
container.Resolve(registration.RegisteredType, registration.Name);
}
}
}
And when I run this test I get an error:
InvalidOperationException - Operation is not valid due to the current state of the object.
How can I replace LifeTimeManager into Unit test from PerRequestLifetimeManager to another one?
I've just found the solution for this issue:
Just need to add following code before this line in test
UnityConfig.RegisterTypes(container);
var request = new HttpRequest("fake", "https://127.0.0.1", null);
var respons = new HttpResponse(new StringWriter());
var context = new HttpContext(request, respons);
HttpContext.Current = context;