Я создал фоновую службу в android maui, как в этом вопросе: Как создать фоновую службу в .NET Maui. Это работает нормально. Но я не понимаю, как добавить службы DI в этом фоне? Мне нужно добавить IDbContextFactory для моего основного контекста ef и IServiceScopeFactory.
Если я добавлю их в конструкторе, я получаю ошибку:
Error XA4213 The type 'MyBackgroundService' must provide a public default constructor
.
Мой фоновый сервис:
[Service]
public class AndroidBackgroundService : Service, IService
{
UpdateBackgroundService _updateBackgroundService; //I need this DI service
public AndroidBackgroundService(UpdateBackgroundService updateBackgroundService) //This compile error
{
_updateBackgroundService = updateBackgroundService;
}
public AndroidBackgroundService()
{
}
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
[return: GeneratedEnum]//we catch the actions intents to know the state of the foreground service
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
if (intent.Action == "START_SERVICE")
{
RegisterNotification();//Proceed to notify
Run();
}
else if (intent.Action == "STOP_SERVICE")
{
StopForeground(true);//Stop the service
StopSelfResult(startId);
}
return StartCommandResult.NotSticky;
}
public void Run()
{
_updateBackgroundService.Run();
}
//Start and Stop Intents, set the actions for the MainActivity to get the state of the foreground service
//Setting one action to start and one action to stop the foreground service
public void Start()
{
Intent startService = new Intent(Microsoft.Maui.ApplicationModel.Platform.CurrentActivity, typeof(AndroidBackgroundService));
startService.SetAction("START_SERVICE");
Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.StartService(startService);
}
public void Stop()
{
Intent stopIntent = new Intent(Microsoft.Maui.ApplicationModel.Platform.CurrentActivity, this.Class);
stopIntent.SetAction("STOP_SERVICE");
Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.StartService(stopIntent);
}
private void RegisterNotification()
{
NotificationChannel channel = new NotificationChannel("ServiceChannel", "ServiceDemo", NotificationImportance.Max);
NotificationManager manager = (NotificationManager)Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.GetSystemService(Context.NotificationService);
manager.CreateNotificationChannel(channel);
Notification notification = new Notification.Builder(this, "ServiceChannel")
.SetContentTitle("Агент 2 фоновый процесс запущен")
.SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha)
.SetOngoing(true)
.Build();
StartForeground(100, notification);
}
}
Мой UpdateBackgroundService
public class UpdateBackgroundService : BaseBackgroundService
{
private readonly IServiceScopeFactory scopeFactory;
private readonly IDbContextFactory<AsterixDBContext> _DbContextFactoryAsterix;
private readonly IDbContextFactory<Agent2DBContext> _DbContextFactory;
public UpdateBackgroundService(IServiceScopeFactory scopeFactory, IDbContextFactory<Agent2DBContext> dbContextFactory, IDbContextFactory<AsterixDBContext> dbContextFactoryAsterix)
: base(dbContextFactory)
{
this.scopeFactory = scopeFactory;
_DbContextFactoryAsterix = dbContextFactoryAsterix;
_DbContextFactory = dbContextFactory;
}
public Run()
{
...
}
}
МауиПрограмма
builder.Services.AddTransient<UpdateBackgroundService>();
#if ANDROID
builder.Services.AddTransient<AndroidBackgroundService>();
#endif
Да, если бы был простой класс, я бы мог создать их вручную.
Службы, внедренные с помощью DI, должны иметь конструктор по умолчанию (без параметров) или иметь другие службы в качестве параметров, опубликуйте код службы и способ его регистрации, если вам нужна более конкретная помощь.
@Poulpynator Добавлено в вопросы
Вы должны добавить IServiceScopeFactory, IDbContextFactory, ... в качестве сервисов, иначе DI не сможет его разрешить
Проблема не в этом. Я знаю, как работать с ДИ. Я не знаю, как добавить службы DI в фоновую службу Android.
Плохо, не понял, что [Service] не поддерживает параметризованные конструкторы, дал вам ответ, чтобы обойти это
Похоже, что класс [Service] не может иметь никаких параметров в конструкторе, здесь это альтернативный способ использования внедрения зависимостей без передачи параметров.
Создайте класс ServiceProvider
:
public static class ServiceProvider
{
public static TService GetService<TService>()
=> Current.GetService<TService>();
public static IServiceProvider Current
=>
#if WINDOWS10_0_17763_0_OR_GREATER
MauiWinUIApplication.Current.Services;
#elif ANDROID
MauiApplication.Current.Services;
#elif IOS || MACCATALYST
MauiUIApplicationDelegate.Current.Services;
#else
null;
#endif
}
Затем вы можете просто использовать его в любом конструкторе компонентов:
_Contexte = ServiceHelper.GetService<Contexte>();
Имеют ли классы, реализующие ваш DI-интерфейс, параметризованный конструктор?