C
C#2y ago
júlio

❔ Windows BackgroundService

Hello. So I'm a beginner at C# and a beginner and making services, so I'm not sure how stupid some one the questions I'm about to ask might sound. Regardless I would really appreciate if someone could either explain me things or link to useful documentation. I have the following questions regarding Windows Services in C#: 1- From my understanding, the flow of the Service goes as follows (I'll be referring to BackgroundServices, since that is what the documentation advice me to use, apparently it's the modern approach to making a Service in Windows): In the Program.cs file, we have a builder, we give the builder information about the classes that are going to do tasks (?) and then we tell it to .Run(). So I assume this is the code that will run when in the shell I do sc.exe create <service_name.exe>. Please correct me If I'm wrong. Then I need to start the service so that it starts doing the thing I tell it to do, and I would stop it if I wanted to stop the service. To kill the service I would need to delete it. This would all be done using the sc.exe. 2- Still regarding Program.cs, what is a HostApplicationBuilder, and why do I need one? The documentation that I followed (https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service) used a bunch of Host stuff in the Program.cs file but didn't really explained what was going on, so this is my biggest question mark so far, is what is going on with the Program.cs file.
106 Replies
júlio
júlioOP2y ago
using App.WindowsService;
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Logging.EventLog;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddWindowsService(options =>
{
options.ServiceName = ".NET Joke Service";
});

LoggerProviderOptions.RegisterProviderOptions<
EventLogSettings, EventLogLoggerProvider>(builder.Services);

builder.Services.AddSingleton<JokeService>();
builder.Services.AddHostedService<WindowsBackgroundService>();

builder.Logging.AddConfiguration(
builder.Configuration.GetSection("Logging"));

IHost host = builder.Build();
host.Run();
using App.WindowsService;
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Logging.EventLog;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddWindowsService(options =>
{
options.ServiceName = ".NET Joke Service";
});

LoggerProviderOptions.RegisterProviderOptions<
EventLogSettings, EventLogLoggerProvider>(builder.Services);

builder.Services.AddSingleton<JokeService>();
builder.Services.AddHostedService<WindowsBackgroundService>();

builder.Logging.AddConfiguration(
builder.Configuration.GetSection("Logging"));

IHost host = builder.Build();
host.Run();
This is the code in the file, for reference. I have more questions but I think maybe if I understand the base I might figure out the rest. Main questions I have regarding that code: What is the structure of a Service? What files does it need to have, what files should do what things, is the code in Program.cs always like that? Who calls that code, can I rename the file Program.cs, or is it like a file it needs to have? What is each instruction in the Program.cs doing, and is it standard to do what they did in the guide?
Pobiega
Pobiega2y ago
Do you know what dependency injection is? the core idea here is that all the code in Program.cs is just setting up your service. Its not actually your service itself, its just "glue" code to configure things. HostApplicationBuilder and the Host class are from Microsoft.Extension.Hosting, a namespace that contains what is often called "the .NET generic host" turns out its fairly common to need configuration files, logging and some background workers, so the generic host was made to support this "workflow" DI (dependency injection) is an important component here, as thats what manages most of your objects and their lifetimes during the execution of the program. builder.Services is a IServiceCollection, which is the object that is used to configure your DI setup (before being built) the last 2 rows just build the builder into a host, kind of like baking a cake once the dough is mixed, and then it finally runs the host, which will run your IHostedService, in this case... WindowsBackgroundService
júlio
júlioOP2y ago
I don not know what dependency injection is.
Pobiega
Pobiega2y ago
Then I suggest you try to find out. It will be important.
júlio
júlioOP2y ago
I will, thank you for mentioning that. So there is one thing I didn't understand. You mentioned that " its fairly common to need configuration files, logging and some background workers". Does this mean that I am making a Service that contains BackgroundWorkers? See, the main issue here is that I lack understanding that I didn't get from just reading the documentation I linked.
Pobiega
Pobiega2y ago
yes, your entire service is in theory a background worker
júlio
júlioOP2y ago
So the JokeService and WindowsBackgroundService are what exactly? They are both combined into a single service when I build?
Pobiega
Pobiega2y ago
JokeService is ... something. Its registered as a singleton, so there can only be one of them WindowsBackgroundService is a class that implements IHostedService (or BackgroundWorker)
júlio
júlioOP2y ago
So, with the builder.Services.Addxxx syntax, what am I doing exactly?
Pobiega
Pobiega2y ago
adding things to your DI service provider basically telling the DI what things will be available and what lifetimes they have
júlio
júlioOP2y ago
I might be getting off by the class names. JokeService and WindowsBackgroundService aren't actually Services, or are they?
Pobiega
Pobiega2y ago
WindowsBackgroundService is. JokeService can be, but there are no restrictions on it (since its being added by the generic AddSingleton method, that has no requirements) its likely just a "logic class"
júlio
júlioOP2y ago
So in the end, I would have listed in the Service Control Manager a single Service named ".NET Joke Service". And that service would have a service running within itself of type WindowsBackgroundService? (or more, if I added them to the buid.Services) (In this case, JokeService is just a logic class like you mentioned)
Pobiega
Pobiega2y ago
Your entire program will be the "service" listed in the service control manager
júlio
júlioOP2y ago
So the Service name is just a node to N services?
Pobiega
Pobiega2y ago
?
júlio
júlioOP2y ago
Let's say I have 3 more classes similar to WindowsBackgroundService. Let's also say that, in the Program.cs, I do builder.Services.AddHostedService to each of them. When I start my Service, what would happen, would the Service have 4 total intances, one for each type, or would the Service just be a Node to 4 independent Services, one for each type? This is what I'm not understanding.
Pobiega
Pobiega2y ago
not sure what you mean by "Node" here its not a relevant term
júlio
júlioOP2y ago
A folder something that groups things the name of a set
Pobiega
Pobiega2y ago
okay, thats not what Node means, but yeah
júlio
júlioOP2y ago
It could mean that
Pobiega
Pobiega2y ago
your "service", which is actually your program, would run all 4 hosted services simultaneously
júlio
júlioOP2y ago
And these 4 hosted services would be independent of each other?
Pobiega
Pobiega2y ago
yes and/or no 🙂 they can be, they can also not be
júlio
júlioOP2y ago
So they are related entities
Pobiega
Pobiega2y ago
perhaps they send messages to eachother when "things" happen or they dont they CAN be. but they each got started individually and they all have access to the same services (via the DI service provider) so its not at all unreasonable to think that they might use one of those services to communicate
júlio
júlioOP2y ago
I was assigned a task to separete a big service into smaller ones. This is so that I can then learn how to use Kubernetes to orquestrat them, after I pujt them in containers. If I understand things correctly, in the Program.cs file, doing builder.Services.AddHostedService for each of them (assuming I have a type of each of them), would not do it, I would need separate projects for each, correct?
Pobiega
Pobiega2y ago
If you are going to use kubernetes, then they need to be separate executables yes k8 isnt aware of the concept of windows services. it runs programs. the term "service" is incredibly overloaded and means different things in different contexts, just so we got that clear 🙂 it means one thing in C#, one in windows, one in linux, one in kubernetes etc
júlio
júlioOP2y ago
Okay things are starting to make more sense. Thank you so far for the patience you are having, I can be slow when I don't understand concepts at first. Yes I agree that Service has too many different meanings, maybe that is part of why I'm having a bit of trouble at first. I have another question. Services don't really have a Main function, they just provide functionalities, kinda like a library. This is correct, yes?
Pobiega
Pobiega2y ago
They don't have a Main function as such (since thats an application entrypoint), but they do have something... similar
júlio
júlioOP2y ago
You are referring to the ExecuteAsync function, correct?
Pobiega
Pobiega2y ago
sure, or StartAsync/StopAsync depends on what base you use
júlio
júlioOP2y ago
Notice the following code that I used from the guide I previously linked:
namespace App.WindowsService;

public sealed class WindowsBackgroundService : BackgroundService
{
private readonly JokeService _jokeService;
private readonly ILogger<WindowsBackgroundService> _logger;

public WindowsBackgroundService(
JokeService jokeService,
ILogger<WindowsBackgroundService> logger) =>
(_jokeService, _logger) = (jokeService, logger);

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
string joke = _jokeService.GetJoke();
_logger.LogWarning("{Joke}", joke);

await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}
catch (TaskCanceledException)
{
// When the stopping token is canceled, for example, a call made from services.msc,
// we shouldn't exit with a non-zero exit code. In other words, this is expected...
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);

Environment.Exit(1);
}
}
}
namespace App.WindowsService;

public sealed class WindowsBackgroundService : BackgroundService
{
private readonly JokeService _jokeService;
private readonly ILogger<WindowsBackgroundService> _logger;

public WindowsBackgroundService(
JokeService jokeService,
ILogger<WindowsBackgroundService> logger) =>
(_jokeService, _logger) = (jokeService, logger);

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
string joke = _jokeService.GetJoke();
_logger.LogWarning("{Joke}", joke);

await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}
catch (TaskCanceledException)
{
// When the stopping token is canceled, for example, a call made from services.msc,
// we shouldn't exit with a non-zero exit code. In other words, this is expected...
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);

Environment.Exit(1);
}
}
}
The main question I have is this, I never really interacted with Services before, let alone developed one. How would I interact with this service if I wanted to? The service works autonomously as is, but let's say I wanted to pass it something and wait for a output, how would I do that in a Service?
Pobiega
Pobiega2y ago
you wouldn't services are by nature entirely self-contained they dont take input as such if you need that, you'll be wanting to base your service on something that allows input, such as an HTTP service (ASP.NET), or a TCP listener
júlio
júlioOP2y ago
Don't they work be requests? My task is to make a service that a Delphi program would pass in a JSON file, the service would do some parsing, convert that to a HTTP request, send the resquest to a server elsewere, and parse the responce back to JSON and to the Delphi application
Pobiega
Pobiega2y ago
how would the delphi program "pass the json"? by what protocol?
júlio
júlioOP2y ago
Sorry, I might have not typed things in the correct way It passes by parameter
Pobiega
Pobiega2y ago
? how? Things cant just magically talk to other things my webbrowser uses HTTP to talk to web servers a game might use UDP to send packets to the game server
júlio
júlioOP2y ago
I will ask it to the previous maintainer of the project, I'll reply shortly.
Pobiega
Pobiega2y ago
you need to establish a connection between two things for them to talk. Thats done over some form of protocol. On linux, the simplest way would be either file streams, or pipes today, its very common to use HTTP, even if you dont serve webpages its just convenient to spin up a simple webserver that has an API you can talk to
júlio
júlioOP2y ago
Okay so, there is a RestAPI Delphi communicates to the API via URL
Pobiega
Pobiega2y ago
right, so your service is actually a webservice meaning you should NOT be basing it on the above code, but rather on ASP.NET
júlio
júlioOP2y ago
something like https://service-url.com?parm=1&parm=2 etc I see, so different kind of project entirely?
Pobiega
Pobiega2y ago
yep its gonna be fairly similar thou but it uses a different boilerplate you'll still use a builder and a host and builder.services.add...
júlio
júlioOP2y ago
I see, so I assume this is why I would use something called IIS?
Pobiega
Pobiega2y ago
no dear god no
júlio
júlioOP2y ago
Not sure what that is yet tho, it's something they told me I would use
Pobiega
Pobiega2y ago
asp.net comes with a very good webserver called "Kestrel" you do NOT need to use IIS in fact, I highly recommend you don't
júlio
júlioOP2y ago
Does it need a licence?
Pobiega
Pobiega2y ago
nope
júlio
júlioOP2y ago
Okay, so for the rest of the day I will read documentation regarding ASP.NET Services? Is that the correct name for me to look for?
Pobiega
Pobiega2y ago
Microsoft
ASP.NET Web APIs | Rest APIs with .NET and C#
Build secure REST APIs with C# that reach a broad range of clients, including browsers and mobile devices. Build and deploy on Linux, macOS, and Windows.
Pobiega
Pobiega2y ago
this is what you want.
júlio
júlioOP2y ago
Thank you a bunch. I would need to set up a VM to test the service, correct? Does the link you posted regard that?
Pobiega
Pobiega2y ago
no? you dont need a VM it runs just fine on your local machine when you are happy with it, you'd make a container using docker or something similar kubernetes runs containers
júlio
júlioOP2y ago
I was told I would need a VM for this, but no one has really worked with this here, it's kind of a new thing we are trying to use and the project was assigned to me. Anyways, your help has been very helpful. I really appreciate it. I'll surely come here again with more question in the near future. Thanks.
Pobiega
Pobiega2y ago
you'll not need a local VM, but you really do need to read up on a lot of things.. ASP.NET web apis Docker Kubernetes networking (basics) this should take you a few weeks/months to learn 🙂
júlio
júlioOP2y ago
Yes, the kubernets will be a big thing, I have a lot of reading and studying to do...
Pobiega
Pobiega2y ago
yep.
júlio
júlioOP2y ago
I guess this is the part of my career that I get good ahahaha
Pobiega
Pobiega2y ago
my number one tip there is to download and learn "k9s" its a kubernetes tool that makes life soooooo much better I use it all the time https://k9scli.io/
júlio
júlioOP2y ago
Thank you for mentioning that, I was not aware of that tool, I'll definitly chek it out after I get the services running
Pobiega
Pobiega2y ago
you can visually move around in the cluster, inspecting nodes, pods, namespaces, even edit things (but I recommend using something like helm for this)
júlio
júlioOP2y ago
Noted Is it fine to reuse this thread to continue with the questions when I have them? Or would It make more sense to make a new thread for each question?
Pobiega
Pobiega2y ago
sure, if its still open the bot will ask if its still relevant after 24 hours of inactivity threads are not usually meant for really long ongoing things as such
júlio
júlioOP2y ago
I see I'll get to the ASP.NET documentation and try to get something working. I have a better understanding regarding Services after your explanation now Thank you. :) 1º - https://learn.microsoft.com/en-us/aspnet/core/web-api/?WT.mc_id=dotnet-35129-website&view=aspnetcore-7.0 2º - https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-7.0&tabs=visual-studio The documentation you linked refers to the first link and that link refers to the second link if my goal is to create a minimal web API. I think I want the second link, correct? Since the goal is to make a bunch of Web Services, and from reading a bit, it seems more suited to put in a container since they would have minimal dependencies.
Pobiega
Pobiega2y ago
thats not what "minimal" in minimal api refers to its a design decision, controllers vs minimal api they do the same thing, they just look different but if your API is very simple, with a low number of endpoints, minimal API is a good fit
júlio
júlioOP2y ago
The original Service basically handles a bunch of requests to different places, and the main goal is to split that, to make a service for each kind of place I think it's a minimal thing from my understanding
Pobiega
Pobiega2y ago
What does that mean? Will your delphi application contact multiple internal services? that doesnt seem like a good idea. I'd want my client application to have a single endpoint it talks to, and have that service be responsible for any further subdivision if needed (but if all you do is turn a json payload into a web request and returns it, why even bother splitting it)
júlio
júlioOP2y ago
This is a finance related requests The issue we were having is that some kinds of requests are more commum then others and we are talking about a huge number or requests
Pobiega
Pobiega2y ago
Sure
júlio
júlioOP2y ago
so in orther to scale things we want to split into services so that its possible to scale the things that need scaling and not the whole thing plus we would get deployment advantages doing work on a particular service woulnt need to deploy the whole thing etc
Pobiega
Pobiega2y ago
so, that makes sense, if the work is actually being done on your end but you said all it does is forward a request thats not very load intensive, even for a ton of requests if you actually do some "real work" as part of the request, then yes, splitting might make sense
júlio
júlioOP2y ago
it's a bit intensive yes, because we have a very big number of clients, and because the places we talk to do not keep track of sesison, so talking to them needs a bunch of requests to happen this is because in my country its a pain to deal with the apis of the finance and legal stuff, it forces us to have to work around that its gets a bit load intensive
Pobiega
Pobiega2y ago
hm okay. it will be a bit messy for your delphi client to coordinate, but it can work kubernetes can handle scaling and load balancing for you, but the requests must still be directed to the correct place. You might want to consider an API gateway that can act as a single point of entry, so your delphi client can still have the nice "single connection" thing
júlio
júlioOP2y ago
kinda like a router?
Pobiega
Pobiega2y ago
but its actually talking to the gateway that redirects all the requests to their dedicated clusters yeah, thats what an API gateway is
júlio
júlioOP2y ago
How would that affect my design? so the entry point is the API gateway, its job is I assume to figure out what kind of request is, and forward it to the ASP.NET Service that handles that type of request? and also the API gateway would also need to reply to the client. Something like this?
Pobiega
Pobiega2y ago
Pobiega
Pobiega2y ago
so for example, your gateway might get requests that look like...
your.gateway/finance/?param=asd
your.gateway/bank/?param=asd
your.gateway/currency/?param=asd
your.gateway/finance/?param=asd
your.gateway/bank/?param=asd
your.gateway/currency/?param=asd
each of those three routes (finance, bank, currency) would in this example get routed to their own load balancer the balancer will send it to an available node and if there are none, it would ask kubernetes to start a new node auto-scaling (the nodes here are actually Pods in kubernetes lingo)
júlio
júlioOP2y ago
So that design is taking into account that it will be managed by some orquestrator, in this case k8s, correct?
Pobiega
Pobiega2y ago
yes, all of the boxes except the client would be inside the k8 cluster
júlio
júlioOP2y ago
When making something in this scale, I was not aware that I would take into account the Kubernets Would this be transparent code-wise?
Pobiega
Pobiega2y ago
?
júlio
júlioOP2y ago
Let me draw What I think would be happening
Pobiega
Pobiega2y ago
not sure exactly what you mean by that https://excalidraw.com/ if you need a good fast drawing tool 🙂 entirely webbased too
júlio
júlioOP2y ago
Thanks I was using paint :p Iill try taht
júlio
júlioOP2y ago
júlio
júlioOP2y ago
I apologise in advance for my horrible mouse letter This is from the project point of view
Pobiega
Pobiega2y ago
yep
júlio
júlioOP2y ago
I would have a Project for the API Gateway, and a project for each of the service, correct? Kuberenets desgin would be like the image you shared
Pobiega
Pobiega2y ago
well, there are ready made api gateways and load balancers you could use not having to make your own the only thing you'd code on your own was the services
júlio
júlioOP2y ago
Hm, I would have to ask If I can do that, since I'm not 100% sure they want to rely on something that would not be maintained by us to use
Pobiega
Pobiega2y ago
Wouldn't recommend writing your own - its not as easy as it sounds.
júlio
júlioOP2y ago
That was going to be my next question, i see What options out there do I have?
Pobiega
Pobiega2y ago
making one is easy. making a good one is very hard.
júlio
júlioOP2y ago
Interesting
Pobiega
Pobiega2y ago
I'm no expert, but I've heard good things about "KrakenD"
júlio
júlioOP2y ago
This is going to be a challenge for me, It's the first time I'm actually using all this new technology The website seems nice, I'll definitly consider using it The services would still be ASP.NET services correct, even if I don't talk with them directly from the Delphi client?
Pobiega
Pobiega2y ago
yep, they are still normal http services
júlio
júlioOP2y ago
Okay, I think I have enough information to start reading and trying things out. Would you recommend me starting form something in particular? I was thinking about starting with the ASP.NET Services first, then see if they behave correctly, then set up the API Gateway, check that, and then move to Docker and Kubernets. This seems like a good approach, small steps at a time, but I could be wrong
Pobiega
Pobiega2y ago
yeah that seems fine
júlio
júlioOP2y ago
Alright, thank you again for walking me thru all this, I'd probably still be making BackgroundServices by this time and thinking I was making progress ahahaha
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<TodoDb>(opt => opt.UseInMemoryDatabase("TodoList"));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
var app = builder.Build();

var todoItems = app.MapGroup("/todoitems");

todoItems.MapGet("/", GetAllTodos);
todoItems.MapGet("/complete", GetCompleteTodos);
todoItems.MapGet("/{id}", GetTodo);
todoItems.MapPost("/", CreateTodo);
todoItems.MapPut("/{id}", UpdateTodo);
todoItems.MapDelete("/{id}", DeleteTodo);

app.Run();

static async Task<IResult> GetAllTodos(TodoDb db)
{
return TypedResults.Ok(await db.Todos.ToArrayAsync());
}

static async Task<IResult> GetCompleteTodos(TodoDb db)
{
return TypedResults.Ok(await db.Todos.Where(t => t.IsComplete).ToListAsync());
}

static async Task<IResult> GetTodo(int id, TodoDb db)
{
return await db.Todos.FindAsync(id)
is Todo todo
? TypedResults.Ok(todo)
: TypedResults.NotFound();
}

static async Task<IResult> CreateTodo(Todo todo, TodoDb db)
{
db.Todos.Add(todo);
await db.SaveChangesAsync();

return TypedResults.Created($"/todoitems/{todo.Id}", todo);
}

static async Task<IResult> UpdateTodo(int id, Todo inputTodo, TodoDb db)
{
var todo = await db.Todos.FindAsync(id);

if (todo is null) return TypedResults.NotFound();

todo.Name = inputTodo.Name;
todo.IsComplete = inputTodo.IsComplete;

await db.SaveChangesAsync();

return TypedResults.NoContent();
}

static async Task<IResult> DeleteTodo(int id, TodoDb db)
{
if (await db.Todos.FindAsync(id) is Todo todo)
{
db.Todos.Remove(todo);
await db.SaveChangesAsync();
return TypedResults.Ok(todo);
}

return TypedResults.NotFound();
}
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<TodoDb>(opt => opt.UseInMemoryDatabase("TodoList"));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
var app = builder.Build();

var todoItems = app.MapGroup("/todoitems");

todoItems.MapGet("/", GetAllTodos);
todoItems.MapGet("/complete", GetCompleteTodos);
todoItems.MapGet("/{id}", GetTodo);
todoItems.MapPost("/", CreateTodo);
todoItems.MapPut("/{id}", UpdateTodo);
todoItems.MapDelete("/{id}", DeleteTodo);

app.Run();

static async Task<IResult> GetAllTodos(TodoDb db)
{
return TypedResults.Ok(await db.Todos.ToArrayAsync());
}

static async Task<IResult> GetCompleteTodos(TodoDb db)
{
return TypedResults.Ok(await db.Todos.Where(t => t.IsComplete).ToListAsync());
}

static async Task<IResult> GetTodo(int id, TodoDb db)
{
return await db.Todos.FindAsync(id)
is Todo todo
? TypedResults.Ok(todo)
: TypedResults.NotFound();
}

static async Task<IResult> CreateTodo(Todo todo, TodoDb db)
{
db.Todos.Add(todo);
await db.SaveChangesAsync();

return TypedResults.Created($"/todoitems/{todo.Id}", todo);
}

static async Task<IResult> UpdateTodo(int id, Todo inputTodo, TodoDb db)
{
var todo = await db.Todos.FindAsync(id);

if (todo is null) return TypedResults.NotFound();

todo.Name = inputTodo.Name;
todo.IsComplete = inputTodo.IsComplete;

await db.SaveChangesAsync();

return TypedResults.NoContent();
}

static async Task<IResult> DeleteTodo(int id, TodoDb db)
{
if (await db.Todos.FindAsync(id) is Todo todo)
{
db.Todos.Remove(todo);
await db.SaveChangesAsync();
return TypedResults.Ok(todo);
}

return TypedResults.NotFound();
}
So I finished the following tutorial: https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-7.0&tabs=visual-studio I tested things out and everything seems Okay, I understood the concept which is nice. I do have some questions. First of all, that code is all in the Program.cs file. Is there a way to move the functions to another file, so that it's cleaner? If I just create a file and make a namespace TodoApi, and start writing the function definitions, will It recognize them? Also, there is something I'm a bit worried about The previous service had a helper thing inside it, and that helper thing is basically a Parser The need for this Parser is the following, the servers that I will communicate they dont reply in JSON they reply the actual web page so I need to Parse the response, cut down everything I don't need, so that I can work with the data This Parser should be common to all the services I make from the bigger one What alternatives to I have in this situation?
Pobiega
Pobiega2y ago
Absolutely, just make a static class with a static method and you can map that, or look into something like https://fast-endpoints.com/
FastEndpoints
FastEndpoints
FastEndpoints is a developer friendly alternative to Minimal APIs & MVC for rapid REST API development.
Pobiega
Pobiega2y ago
make a class library that all the other services can then import if your reply is in HTML, the term you're looking for is actually a web scraper - I suggest using something like AngleSharp to find the information you need
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?