Is it possible to have a service API that can handle API request / responses, but also have an internal service running on a timer. e.g Every 2 hours check database Logs and delete info logs, something like that?
Asp.Net Core is like any other .NET Core application, it has a Main function where you can start all non-blocking operations you want.
In Program.cs:
public static void Main(string[] args)
{
//Here you can start your timer (maybe using a dedicated class)
//Just avoid blocking code...
//Starting Asp.Net Core web host.
BuildWebHost(args).Run();
}
If you find more confortable, you can do the same inside Configure/ConfigureServices methods in your Startup.cs file, hopefully creating a specific service for your purpose.
Related
I am working on C# Web API 6.0 project with MediatR. Since I am following clean architecture, I have separate project for Web API and Application. I have useCases in Application project with Queries, Commands and handler.
I have register MediatR to WebApplicationBuilder with reference of class 'ApplicationAssembly'. The 'ApplicationAssembly' class is inside Application project.
API Service Contrainer
public static class ServicesConfigurator
{
public static void Configure(WebApplicationBuilder builder)
{
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAutoMapper(typeof(ApplicationAssembly));
builder.Services.AddMediatR(typeof(ApplicationAssembly).GetTypeInfo().Assembly);
}
The above code don't work the way I register MediatR
Exception thrown: 'System.AggregateException' in Microsoft.Extensions.DependencyInjection.dll
if I changed to
builder.Services.AddMediatR(typeof(Program));
then I get following error
One or more errors occurred. (Error constructing handler for request of type MediatR.IRequestHandler`2[SalaryTracker.Application.UseCases.User.Queries.GetUser, SalaryTracker.Application.WrapperDTOs.UserWrapperDataView]. Register your handlers with the container. See the samples in GitHub for examples.)
I have downloaded template and creating sample task application.
From below reference I found Web API auto generated from my task service class.
Dynamic web api generation
So how can I stop this behaviour or make changes in this behavior.
You can easily disable an application service to expose its methods as Web API actions.
Just use [RemoteService(false)] attribute on application service class or application service interface.
[RemoteService(IsEnabled = false)]
public class UserAppService : ApplicationService, IUserAppService
{
}
for mass operation, use #aaron's method.
Comment out the lines mentioned on that page.
ASP.NET MVC 5
// Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
// .ForAll<IApplicationService>(typeof(AbpProjectNameApplicationModule).Assembly, "app")
// .Build();
https://github.com/aspnetboilerplate/module-zero-template/blob/c0d7f0433d573a8207b27f817e1d188c215f1e50/src/AbpCompanyName.AbpProjectName.WebApi/Api/AbpProjectNameWebApiModule.cs#L17-L19
ASP.NET Core
// Configuration.Modules.AbpAspNetCore()
// .CreateControllersForAppServices(
// typeof(AbpProjectNameApplicationModule).GetAssembly()
// );
https://github.com/aspnetboilerplate/module-zero-core-template/blob/bb9d5aab6e5047d6d22d49831b473c0b3329b499/aspnet-core/src/AbpCompanyName.AbpProjectName.Web.Core/AbpProjectNameWebCoreModule.cs#L44-L47
I attempted to reproduce the method described in this great article by Andrew Lock. However, I am unable to get this running in a .NET core 1.1 console application. When the appsettings.json file is changed and saved, the changes are not reflected in the application without restarting it.
There are multiple files involved, so I created the smallest example I could come up on github. I also provided details in the README.MD file on github.
Any help in resolving this would be most appreciated. Please keep in mind I am new to .NET core, and not an experienced developer. And this is my first question on stackoverflow... Thanks in advance!
The key thing to understand is scope.
There are three scopes in ASP.NET Core - transient, scoped, and singleton. IOptionsSnapshot is configured as a scoped service.
In ASP.NET Core, a scope is started for every request, so every request, you would get a new instance of IOptionsSnapshot, with updated configuration values.
In the example you provided, you are creating an IServiceProvider, and are fetching an instance of IMyService directly from the top level provider:
IServiceCollection services = new ServiceCollection();
Startup startup = new Startup();
startup.ConfigureServices(services);
IServiceProvider serviceProvider = services.BuildServiceProvider();
while (true)
{
var service = serviceProvider.GetService<IMyService>();
var reply = service.DoSomething();
Console.WriteLine(reply);
}
Essentially, you're always using the same scope for every request to the service provider, so you're always getting the same instance of IOptionsSnapshot. Effectively, if you never create a new scope, all of your scoped services become singletons!
The way to fix this is to create a new scope each time you fetch the service:
IServiceCollection services = new ServiceCollection();
Startup startup = new Startup();
startup.ConfigureServices(services);
IServiceProvider serviceProvider = services.BuildServiceProvider();
while (true)
{
using (var scope = serviceProvider.CreateScope())
{
var service = scope.ServiceProvider.GetService<IMyService>();
var reply = service.DoSomething();
Console.WriteLine(reply);
}
}
This also becomes important if you're doing things like creating an EF Core DbContext outside the context of a request in ASP.NET Core app (or in a console app). Always create a new scope before accessing services from the service provider!
P.S. I've created a pull request to fix your sample :)
I read a lot about SignalR and wondering about how to use it with ASP.NET WebAPI. It seems that the WebAPI route config made the SignalR connection not able to connect to Hub and I don't know how to set up correctly to make this 2 things work together.
The two should not conflict if you have not configured the webapi framework to override some of SignalR default routes like ~/signalr/hubs
[assembly: OwinStartup(typeof(SignalRConfig))]
namespace MyApp.App_Start
{
public static class SignalRConfig
{
public static void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
Thats what you need for signalr to hook up, and then include the client side scripts
#Scripts.Render("~/signalr/hubs") and #Scripts.Render("~/Scripts/jquery.signalR-{version}.js")
Here is an example were I use them together
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/tree/master/SignalR.EventAggregatorProxy.Demo.MVC4
I'm currently evaluating WebAPI and NancyFx for a new project about to start. I've managed to get Nancy to self host from a test assembly (by itself it uses asp.net hosting).
Is there any way to do the same with Web API? I would like to keep the web api project hosted on IIS, but i would like to spin it up from my test assembly, so i can run tests against it.
I have found some blogposts on how to use Autofac to scan controllers from another assembly (seems a little backwards only to get hosting from another assembly to work, but if it can be done, i guess that would be an option), but i would like to keep using Structuremap ioc for this project.
Managed to get it working with help from Mark Jones link. This is what i ended up with in my test assembly.
private static HttpSelfHostServer _server;
[BeforeTestRun]
public static void Setup()
{
var config = new HttpSelfHostConfiguration(Settings.TestUri);
WebApiConfig.Register(config); //map routes
IocConfig.Bootstrap(config); //configure dependency injection
_server = new HttpSelfHostServer(config);
_server.OpenAsync().Wait();
}
[AfterTestRun]
public static void TearDown()
{
_server.CloseAsync().Wait();
}