For Xamarin projects to display Date picker in popup I used Acr.UserDialogs, but it is not compatible with .NET MAUI.
Is there a port or something like this for .NET MAUI?
If no, how can I display a date popup for a .NET MAUI project?
According to the link you provided, The newest version of the Acr.UserDialogs package has supported the .net maui.
And you can check the package owner's sample which shows how to use Acr.UserDialogs version 8.0.1.
Sample link: https://github.com/aritchie/userdialogs/tree/master/sample/Sample
To use .net6 version of Acr.UserDialogs package, I have to initialize it in MauiProgram instead of MainActivity.
My MauiProgram class looks like that, note the ConfigureLifecycleEvents part. It is relevant to the subject.
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.UseMauiApp<App>().ConfigureFonts(fonts =>
{
// configuring fonts here, (not related to the subject)
})
.ConfigureLifecycleEvents(events =>
{
#if ANDROID
events.AddAndroid(android => android.OnApplicationCreate(app => UserDialogs.Init(app)));
#endif
})
// other useXXXXX() calls (not related to the subject)
return builder.Build();
}
}
To init UserDialogs correctly in Android, to also provide UserDialogs with DependencyInjection (ConstructorInjection) i do it in my MainApplication.cs
protected override MauiApp CreateMauiApp()
{
UserDialogs.Init(this);
return MauiProgram.CreateMauiApp();
}
In this case you can also apply UserDialogs to your DependencyInjection service like
builder.Services.AddSingleton<IUserDialogs>(UserDialogs.Instance);
in your MauiProgram.cs.
So the ConfigureLifecycleEvents isn't needed anymore and you can also avoid this ugly #if pattern ;)
Related
I am going to publish some of the statistics provided by event-counter as metrics.
There are many pre-defined ones in the framework as we can see here.
How I can access the information (that is available through dotnet-counters)?
This is available through the OpenTelemetry packages. In my own applications I use the following to add OpenTelemetry metrics for the runtime and process metrics and publish them to Prometheus :
public static IServiceCollection AddOtelMetrics(
this IServiceCollection services,
string[]? names=null)
{
services.AddOpenTelemetryMetrics(meters =>
{
meters.AddEventCountersInstrumentation(c =>
{
c.AddEventSources("rabbitmq-client");
});
meters.AddAspNetCoreInstrumentation();
meters.AddHttpClientInstrumentation();
meters.AddRuntimeInstrumentation();
meters.AddProcessInstrumentation();
if (names != null)
{
meters.AddMeter(names);
}
meters.AddPrometheusExporter();
});
The AddAspNetCoreInstrumentation, AddRuntimeInstrumentation and AddProcessInstrumentation add the well known meters. Other meters can be added by passing their names to AddMeter. EventSources can also be added, with AddEventCountersInstrumentation and passing the EventSource name.
meters.AddEventCountersInstrumentation(c =>
{
c.AddEventSources("rabbitmq-client");
});
Is there any way to register a "catch all" to the .net core dependency injection? That uses any dependencies it has and makes a instance? I know this worked in old framework apps (using StructureMap) and cant find a way to do it in .net core (without using a extra NuGet package). As a very simple example trying to get UnkownClass throws a exception
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace DICatchAllTest
{
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection().AddLogging()
.AddSingleton<KnownClass>();
var serviceProvider = services.BuildServiceProvider();
serviceProvider.GetRequiredService<UnknownClass>();
}
}
public class KnownClass
{
public KnownClass(ILogger<KnownClass> logger, UnknownClass unknownClass)
{
//Set these to properties to be used late
}
}
public class UnknownClass
{
public UnknownClass(ILogger<UnknownClass> logger)
{
//Set these to properties to be used late
}
}
}
I suppose with "catch all" you mean you'd like the DI-container to find the required types itself without you having to register them. That's indeed a feature that some DI-frameworks have but the .net one does not. However, there are many libraries that allow you to accomplish this. For example Scrutor. Here is an example of how to use it.
As #Steven explained it is not something that is supported by the out of the box .net core DI container. So I will look into a third party container for this functionality.
I would like to use IHttpClientFactory in a WPF application built using the Prism library. I have added two packages, Prism.Unity and Prism.Unity.Extensions and i attempt to register the IHttpClientFactory with the following code:
containerRegistry.RegisterServices(s => s.AddHttpClient("DefaultClient")
.AddPolicyHandler(GetRetryPolicy()));
However, I get the following error:
I have also added the following override:
protected override IContainerExtension CreateContainerExtension() => PrismContainerExtension.Current;
Prism 8 introduces registration methods for scoped services. The IContainerProvider interface declares an additional method CreateScope and a member CurrentScope that were not present in earlier versions.
public interface IContainerProvider {
// ...other members.
IScopedProvider CreateScope();
ScopedProvider CurrentScope { get; }
}
The PrismContainerExtension classes from Prism.Unity.Extensions in version 7.2.0.1054 and earlier do not implement this method. Consequently, you get an exception using it with Prism 8.
Since the types are incompatible, you either have to revert to Prism 7.2.0.1054 or you have to wait for a new version of Prism.Unity.Extensions that supports the new scoped services in Prism 8. There are already changes made in the repository, but a preview version is currently only available to sponsors.
I'm following the next tutorial of IdentityServer4 implementation for API , but I can't call the method AddJsonFormatters() to services.AddMvcCore().
I'm currently configuring the API from an empty template in ASP.NET Core 3.0.0
I have added NuGet package Microsoft.AspNetCore.Mvc.Formatters.Json with no results.
Also, I understand that using AddMvc() instead of AddMvcCore() would be a partial solution but I can't use AddAuthorization() on AddMvc()
//code extracted from the link
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
}
}
This is the error message I see above:
'IMvcCoreBuilder' does not contain a definition for
'AddJsonFormatters' and no accessible extension method
'AddJsonFormatters' accepting a first argument of type
'IMVCoreBuilder' could be found (are you using a missing directive or
an assembly reference?)
Is this the method? Should I send an MVCCoreBuilder? How do I do that? MvcJsonMvcCoreBuilderExtensions.AddJsonFormatters Method
When you call services.AddMvc() you get an IMvcBuilder.
if you want to add more output or input formatters, the IMvcBuilder has an extension method that you can call AddMvcOptions bellow you have an example of an XmlDataContractSerializerOutputFormatter that was added
mvcBuilder.AddMvcOptions(options =>
{
options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
options.InputFormatters.Add(new XmlDataContractSerializerInputFormatter(options));
Mvc already has a JsonOutputFormatter ,so inside of the AddMvcOptions you can get it and also and add your own custom mediatypes if you need it.
var jsonOutputFormatter = options.OutputFormatters.OfType<JsonOutputFormatter>().FirstOrDefault();
if (jsonOutputFormatter != null)
{
jsonOutputFormatter.SupportedMediaTypes.Add(HttpMediaTypes.Vnd+json.all);
jsonOutputFormatter.SupportedMediaTypes.Add(HttpMediaTypes.ApplicationOctetStream);
}
As I understood, there is not class MvcJsonMvcCoreBuilderExtensions in .NET Core 3.0 yet.
Eventually I just added -f parameter when I was created the Api project:
dotnet new web -n Api -f netcoreapp2.2
instead of
dotnet new web -n Api
It makes the Api project for .NET Core 2.2 so you can read the tutorial.
I was having the same issue. I found that I was on the wrong tutorial for implementing it with the current versions of dotnet core. The comment made by -AnorZaken helped:
Check the tutorial again, it has been updated to NetCore3
Look at the top of the sidebar on the tutorial page. If it says "Release" under the IdentityServer4 title, that won't work.
There is a dropdown at the bottom of the sidebar where you can select "3.1" instead.
Use this:
If MVC
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());
.....
.....
if it is API than use
services.AddControllersWithViews().AddNewton ......
I have a console application to test HangFire. Here is the code:
using System;
using Hangfire;
namespace MyScheduler.ConsoleApp
{
internal static class Program
{
internal static void Main(string[] args)
{
MyMethod();
Console.WriteLine("[Finished]");
Console.ReadKey();
}
private static void MyMethod()
{
RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), Cron.Minutely);
}
}
}
But it throws an exception on runtime:
Additional information: JobStorage.Current property value has not been
initialized. You must set it before using Hangfire Client or Server
API.
So I need a job storage to run this. But all examples in SQL storage etc. Is there any way to run this example with some kind of memory storage?
JobStorage.Current = new SqlServerStorage("ConnectionStringName", options);
// to
JobStorage.Current = new MemoryDbStorage(string.Empty, options);
You can use Hangfire.MemoryStorage for this.
Simply add this nuget package.
And then you can use it like -
GlobalConfiguration.Configuration.UseMemoryStorage();
For NET Core (web application):
Just to make it very obvious because it wasn't obvious to me.
Install following nuget packages:
Hangfire.AspNetCore (v1.6.17 atow)
Hangfire.MemoryStorage.Core (v1.4.0 atow)
In Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// other registered services
...
services.AddHangfire(c => c.UseMemoryStorage());
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// other pipeline configuration
...
app.UseHangfireServer();
app.UseMvc();
}
Anything less than above and my enqueued method did not fire.
As Yogi said, you can use Hangfire.MemoryStorage or Hangfire.MemoryStorage.Core (for .Net Core).
What is missing in that answer is the complete code (for .Net Core) that needs to be put inside ConfigureServices(..) :
var inMemory = GlobalConfiguration.Configuration.UseMemoryStorage();
services.AddHangfire(x => x.UseStorage(inMemory));
Just for the sake of completeness the author of the Hangfire library has added a new package titled Hangfire.InMemory the version of which is available on Nuget. The repository readme positions it as targeting production use. A quote github repo URL is as follows "..an efficient transactional in-memory storage for Hangfire with data structures close to their optimal representation. The result of this attempt should enable production-ready usage of this storage implementation and handle particular properties of in-memory processing.."
The familiar configuration concept applies here as well:
GlobalConfiguration.Configuration.UseInMemoryStorage();
I personally added it as follows:
services.AddHangfire(configuration => { configuration.UseInMemoryStorage(); });