Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#依赖项注入有重复的单例_C#_Xamarin_Xamarin.forms_Dependency Injection_Singleton - Fatal编程技术网

C#依赖项注入有重复的单例

C#依赖项注入有重复的单例,c#,xamarin,xamarin.forms,dependency-injection,singleton,C#,Xamarin,Xamarin.forms,Dependency Injection,Singleton,我正在开发一个Xamarin.Forms应用程序,由于某些原因,其中有多次创建的单例。然而,这种情况并非每次都发生,而且似乎是随机发生的。我的依赖项注入设置发生在App.xaml.cs中 using System; using Microsoft.AppCenter; using Microsoft.AppCenter.Analytics; using Microsoft.AppCenter.Crashes; using Microsoft.Extensions.DependencyInject

我正在开发一个Xamarin.Forms应用程序,由于某些原因,其中有多次创建的单例。然而,这种情况并非每次都发生,而且似乎是随机发生的。我的依赖项注入设置发生在App.xaml.cs中

using System;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using Microsoft.Extensions.DependencyInjection;
using Peripass.Mobile.Framework;
using Peripass.Mobile.Framework.DependencyInterfaces;
using Peripass.YardAssetManagementApp.Data;
using Peripass.YardAssetManagementApp.Data.FileSystem;
using Peripass.YardAssetManagementApp.Data.LocalDataServices;
using Peripass.YardAssetManagementApp.Data.Queues;
using Peripass.YardAssetManagementApp.Data.RemoteDataServices;
using Peripass.YardAssetManagementApp.Data.Syncing;
using Peripass.YardAssetManagementApp.Data.Syncing.QueueItemSyncActions;
using Peripass.YardAssetManagementApp.Device;
using Peripass.YardAssetManagementApp.MVVM;
using Peripass.YardAssetManagementApp.MVVM.Pages;
using Peripass.YardAssetManagementApp.PushNotifications;
using Peripass.YardAssetManagementApp.Services;
using Peripass.YardAssetManagementApp.StepsWizard;
using Peripass.YardAssetManagementApp.UI.Views;
using Peripass.YardAssetManagementApp.UserAuthentication;
using Peripass.YardAssetManagementApp.ViewModels;
using Xamarin.Forms;
using Application = Xamarin.Forms.Application;

namespace Peripass.YardAssetManagementApp {
  public partial class App : Application, IApp {
    private string _startedByAndroidNotificationMessage;
    
    public App() {
      ConfigureServices();
      InitializeComponent();
      AppCenter.Start($"android={Configuration.Configuration.ApplicationInsightsKeyAndroid};", typeof(Analytics), typeof(Crashes));
      MainPage = ServiceProvider.GetRequiredService<MainPage>();
    }

    public static IServiceCollection Services { get; } = new ServiceCollection();
    public IServiceProvider ServiceProvider { get; set; }

    private void ConfigureServices() {
      Services.AddSingleton<ILifecycleHooksService, LifecycleHooksService>();
      Services.AddTransient<INetworkInformationProvider, NetworkInformationProvider>();

      RegisterLocalDataServices();
      RegisterRemoteDataServices();
      RegisterSyncLogic();
      RegisterServices();

      RegisterViews();
      Services.AddSingleton<IUserManager, UserManager>();
      Services.AddSingleton<HttpClientProvider>();
      Services.AddSingleton<ILogger, Logger>();
      Services.AddSingleton<INavigationService, NavigationService>();
      Services.AddSingleton<StepsWizardManager>();
      Services.AddSingleton<MainPage>();
      Services.AddSingleton(DependencyService.Get<ILocalFileSystem>());
      Services.AddSingleton<IRestServiceHelper, RestServiceHelper>();
      Services.AddSingleton<IPushNotificationsService, PushNotificationsService>();
      ServiceProvider = Services.BuildServiceProvider();
    }

    public void RegisterServices() {
      Services.AddTransient<ITaskService, TaskService>();
      Services.AddTransient<ILocationService, LocationService>();
      Services.AddTransient<ILocalizationService, LocalizationService>();
      Services.AddTransient<IDiagnosticsService, DiagnosticsService>();
    }

    public void RegisterLocalDataServices() {
      Services.AddSingleton<ILocalTaskDataService, LocalTaskDataService>();
      Services.AddSingleton<ILocalLocationDataService, LocalLocationDataService>();
      Services.AddSingleton<ILocalUserDataService, LocalUserDataService>();
      Services.AddSingleton<ILocalPushNotificationDataService, LocalPushNotificationDataService>();
      Services.AddSingleton<ILocalPictureDataService, LocalPictureDataService>();
      Services.AddSingleton<ISafeFileSystem, SafeFileSystem>();
      Services.AddSingleton<ILocalLocalizationDataService, LocalLocalizationDataService>();
    }

    public void RegisterRemoteDataServices() {
      Services.AddSingleton<IRemoteTaskDataService, RemoteTaskDataService>();
      Services.AddSingleton<IRemoteLocationDataService, RemoteLocationDataService>();
      Services.AddSingleton<IRemoteUserDataService, RemoteUserDataService>();
      Services.AddSingleton<IRemoteFileDataService, RemoteFileDataService>();
      Services.AddSingleton<IRemoteLocalizationDataService, RemoteLocalizationDataService>();
    }

    public void RegisterSyncLogic() {
      Services.AddSingleton<IToMobileTasksSyncer, ToMobileTasksSyncer>();

      Services.AddSingleton<IQueue, IncomingHighPriorityQueue>();
      Services.AddSingleton<IQueue, IncomingLowPriorityQueue>();
      Services.AddSingleton<IQueue, OutgoingHighPriorityQueue>();
      Services.AddSingleton<IQueue, OutgoingLowPriorityQueue>();
      Services.AddSingleton<IQueue, PictureSyncLowPriorityQueue>();
      Services.AddSingleton<IQueue, PictureSyncHighPriorityQueue>();

      Services.AddSingleton<IQueueOrchestrator, IncomingQueueOrchestrator>();
      Services.AddSingleton<IQueueOrchestrator, OutgoingQueueOrchestrator>();
      Services.AddSingleton<IQueueOrchestrator, PictureQueueOrchestrator>();

      Services.AddSingleton<IQueueProcessor, IncomingQueueProcessor>();
      Services.AddSingleton<IQueueProcessor, OutgoingQueueProcessor>();
      Services.AddSingleton<IQueueProcessor, PictureQueueProcessor>();

      Services.AddSingleton<IQueueItemSyncAction, FetchTaskDetailSyncAction>();
      Services.AddSingleton<IQueueItemSyncAction, OutgoingStepValueUpdateSyncAction>();
      Services.AddSingleton<IQueueItemSyncAction, OutgoingTaskStatusChangedSyncAction>();
      Services.AddSingleton<IQueueItemSyncAction, SyncPictureAction>();

      Services.AddSingleton<IFileIntegrityHelper, FileIntegrityHelper>();
    }

    public void RegisterViews() {
      Services.AddTransient<LoginViewContent>();
      Services.AddSingleton<LoginViewModel>();

      Services.AddTransient<UserInfoViewContent>();
      Services.AddSingleton<UserInfoViewModel>();

      Services.AddTransient<MainTaskListViewContent>();
      Services.AddSingleton<MainTaskListViewModel>();

      Services.AddTransient<TaskDetailViewContent>();
      Services.AddSingleton<TaskDetailViewModel>();

      Services.AddTransient<IntegerFieldTaskStepViewContent>();
      Services.AddSingleton<IntegerFieldTaskStepViewModel>();

      Services.AddTransient<TextAreaTaskStepViewContent>();
      Services.AddSingleton<TextAreaTaskStepViewModel>();

      Services.AddTransient<DropDownTaskStepViewContent>();
      Services.AddSingleton<DropDownTaskStepViewModel>();

      Services.AddTransient<MoveToLocationSummaryViewContent>();
      Services.AddSingleton<MoveToLocationSummaryViewModel>();

      Services.AddTransient<TakePictureStepViewContent>();
      Services.AddSingleton<TakePictureStepViewModel>();

      Services.AddTransient<MoveToLocationStepViewContent>();
      Services.AddSingleton<MoveToLocationStepViewModel>();

      Services.AddTransient<TaskCompletedViewContent>();
      Services.AddSingleton<TaskCompletedViewModel>();

      Services.AddTransient<LoggedOutViewContent>();
      Services.AddSingleton<LoggedOutViewModel>();

      Services.AddTransient<TextFieldTaskStepViewContent>();
      Services.AddSingleton<TextFieldTaskStepViewModel>();

      Services.AddTransient<DecimalFieldTaskStepViewContent>();
      Services.AddSingleton<DecimalFieldTaskStepViewModel>();

      Services.AddTransient<GenericExceptionPageViewContent>();
      Services.AddSingleton<GenericExceptionPageViewModel>();

      Services.AddTransient<CleanupBeforeLogoutPageViewContent>();
      Services.AddSingleton<CleanupBeforeLogoutPageViewModel>();

      Services.AddTransient<SelectLanguageViewContent>();
      Services.AddSingleton<SelectLanguageViewModel>();
    }

    protected override async void OnStart() {
      await ServiceProvider.GetRequiredService<ILifecycleHooksService>().OnStart();
    }

    protected override void OnSleep() { }

    protected override async void OnResume() {
      await ServiceProvider.GetRequiredService<ILifecycleHooksService>().OnResume();
    }

    public void StartedByTapOnAndroidNotification(string message) {
      _startedByAndroidNotificationMessage = message;
    }
  }
}
使用系统;
使用Microsoft.AppCenter;
使用Microsoft.AppCenter.Analytics;
使用Microsoft.AppCenter.0崩溃;
使用Microsoft.Extensions.DependencyInjection;
使用Peripass.Mobile.Framework;
使用Peripass.Mobile.Framework.dependency接口;
使用Peripass.YardAssetManagementApp.Data;
使用Peripass.YardAssetManagementApp.Data.FileSystem;
使用Peripass.YardAssetManagementApp.Data.LocalDataServices;
使用Peripass.YardAssetManagementApp.Data.Queues;
使用Peripass.YardAssetManagementApp.Data.RemoteDataServices;
使用Peripass.YardAssetManagementApp.Data.Syncing;
使用Peripass.YardAssetManagementApp.Data.Syncing.QueueItemSyncActions;
使用Peripass.YardAssetManagementApp.Device;
使用Peripass.YardAssetManagementApp.MVVM;
使用Peripass.YardAssetManagementApp.MVVM.Pages;
使用Peripass.YardAssetManagementApp.PushNotifications;
使用Peripass.YardAssetManagementApp.Services;
使用Peripass.YardAssetManagementApp.StepsWizard;
使用Peripass.YardAssetManagementApp.UI.Views;
使用Peripass.YardAssetManagementApp.UserAuthentication;
使用Peripass.YardAssetManagementApp.ViewModels;
使用Xamarin.Forms;
使用Application=Xamarin.Forms.Application;
命名空间Peripass.YardAssetManagementApp{
公共部分类应用程序:应用程序,IApp{
由AndroidNotificationMessage启动的私有字符串;
公共应用程序(){
配置服务();
初始化组件();
AppCenter.Start($“android={Configuration.Configuration.ApplicationInsightsKeyAndroid};”,typeof(分析),typeof(崩溃));
MainPage=ServiceProvider.GetRequiredService();
}
公共静态IServiceCollection服务{get;}=newServiceCollection();
公共IServiceProvider服务提供程序{get;set;}
私有void配置服务(){
Services.AddSingleton();
Services.AddTransient();
RegisterLocalDataServices();
RegisterRemoteDataServices();
registerSyncologic();
RegisterServices();
RegisterViews();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton(DependencyService.Get());
Services.AddSingleton();
Services.AddSingleton();
ServiceProvider=Services.BuildServiceProvider();
}
公共无效注册表服务(){
Services.AddTransient();
Services.AddTransient();
Services.AddTransient();
Services.AddTransient();
}
公共无效注册表LocalDataServices(){
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
}
公共无效注册表RemotedataServices(){
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
}
公共无效注册表syncologic(){
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
}
public void RegisterViews(){
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
Services.AddTransient();
Services.AddSingleton();
}
受保护的重写异步void OnStart(){
等待ServiceProvider.GetRequiredService().OnStart();
}
受保护的覆盖void OnSleep(){}
受保护的重写异步void OnResume(){
等待ServiceProvider.GetRequiredService().OnResume();
}
由TAPONANDROIDNotification启动的公共无效(字符串消息){
_startedByAndroidNotificationMessage=消息;
}
}
}
多次创建的单例就是这些单例。可能是其他的单身汉也被创造了很多次,但我确信这些

      Services.AddSingleton<IQueueOrchestrator, IncomingQueueOrchestrator>();
      Services.AddSingleton<IQueueOrchestrator, OutgoingQueueOrchestrator>();
      Services.AddSingleton<IQueueOrchestrator, PictureQueueOrchestrator>();

      Services.AddSingleton<IQueueProcessor, IncomingQueueProcessor>();
      Services.AddSingleton<IQueueProcessor, OutgoingQueueProcessor>();
      Services.AddSingleton<IQueueProcessor, PictureQueueProcessor>();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
Services.AddSingleton();
我看到,在解析ILifecycleHooksService的依赖项时,有时会多次调用OnStart方法来创建这些单例的多个实例。这是LifecycleHookService中的代码:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Peripass.YardAssetManagementApp.Data;
using Peripass.YardAssetManagementApp.Data.LocalDataServices;
using Peripass.YardAssetManagementApp.Data.Syncing;
using Peripass.YardAssetManagementApp.MVVM;
using Peripass.YardAssetManagementApp.PushNotifications;
using Peripass.YardAssetManagementApp.ViewModels;

namespace Peripass.YardAssetManagementApp {
  public interface ILifecycleHooksService {
    Task OnStart();
    Task OnResume();
  }
  public class LifecycleHooksService : ILifecycleHooksService {
    private readonly INavigationService _navigationService;
    private readonly ILocalUserDataService _localUserDataService;
    private readonly ILocalTaskDataService _localTaskDataService;
    private readonly ILocalLocationDataService _localLocationDataService;
    private readonly ILocalPushNotificationDataService _localPushNotificationDataService;
    private readonly ILocalPictureDataService _localPictureDataService;
    private readonly IToMobileTasksSyncer _toMobileTasksSyncer;
    private readonly IEnumerable<IQueueProcessor> _queueProcessors;
    private readonly IPushNotificationsService _pushNotificationsService;
    private readonly ILocalLocalizationDataService _localLocalizationDataService;

    public LifecycleHooksService(INavigationService navigationService,
      ILocalUserDataService localUserDataService, 
      IToMobileTasksSyncer toMobileTasksSyncer, 
      IEnumerable<IQueueProcessor> queueProcessors,
      ILocalTaskDataService localTaskDataService, 
      ILocalLocationDataService localLocationDataService, 
      ILocalPushNotificationDataService localPushNotificationDataService, 
      IPushNotificationsService pushNotificationsService,
      ILocalPictureDataService localPictureDataService, ILocalLocalizationDataService localLocalizationDataService) {

      _navigationService = navigationService;
      _localUserDataService = localUserDataService;
      _toMobileTasksSyncer = toMobileTasksSyncer;
      _queueProcessors = queueProcessors;
      _localTaskDataService = localTaskDataService;
      _localLocationDataService = localLocationDataService;
      _localPushNotificationDataService = localPushNotificationDataService;
      _pushNotificationsService = pushNotificationsService;
      _localPictureDataService = localPictureDataService;
      _localLocalizationDataService = localLocalizationDataService;
    }
    public async Task OnStart() {
      await ReloadData();
      await CreateDeviceIdOnFirstStartAsync();
      var currentUser = _localUserDataService.GetCurrentUser();
      if (currentUser.IsLoggedIn) {
        Configuration.Configuration.SetEnvironment(currentUser.Environment);
        await _navigationService.NavigateToViewModelAsync<MainTaskListViewModel>(true);
        try {
          await _toMobileTasksSyncer.SyncAllMetaData();
        }
        catch {
          // ignored
        }
      }
      else {
        await _navigationService.NavigateToViewModelAsync<LoginViewModel>();
      }
      foreach (var queueProcessor in _queueProcessors) {
        _ = Task.Run(async () => await queueProcessor.StartPeriodicProcessing());
      }
    }

    public async Task OnResume() {
      try {
        await _toMobileTasksSyncer.SyncAllTasks(true);
      }
      catch {
        // ignored
      }
    }

    public async Task CreateDeviceIdOnFirstStartAsync() {
      var currentPushNotificationInfo = await _localPushNotificationDataService.GetCurrentPushNotificationInfo();
      if (string.IsNullOrEmpty(currentPushNotificationInfo.DeviceIdTag)) {
        await _localPushNotificationDataService.SetDeviceId(Guid.NewGuid().ToString());
      }
    }

    private async Task ReloadData() {
      await _localLocalizationDataService.ReloadData();
      await _localUserDataService.ReloadData();
      await _localTaskDataService.ReloadData();
      await _localLocationDataService.ReloadData();
      await _localPictureDataService.ReloadData();
      await _pushNotificationsService.ProcessReceivedMessages();
    }
  }
}

使用系统
// Possible work around for market launches. See https://issuetracker.google.com/issues/36907463
// for more details. Essentially, the market launches the main activity on top of other activities.
// we never want this to happen. Instead, we check if we are the root and if not, we finish.

if (!isTaskRoot()) {
    final Intent intent = getIntent();
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN.equals(intent.getAction())) {
        Log.w(LOG_TAG, "Main Activity is not the root.  Finishing Main Activity instead of launching.");
        finish();
        return;       
    }
}