From b9838ecc4e410e17b19211bb3c3e3e990caa87e9 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 11 Apr 2019 14:14:34 -0400 Subject: [PATCH] service container --- src/Android/MainApplication.cs | 31 ++++++++- src/Core/Services/AppIdService.cs | 2 +- src/Core/Services/PclCryptoFunctionService.cs | 2 +- src/Core/Utilities/ServiceContainer.cs | 66 +++++++++++++++++++ 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/Core/Utilities/ServiceContainer.cs diff --git a/src/Android/MainApplication.cs b/src/Android/MainApplication.cs index 173fdbc9f..5fee117ff 100644 --- a/src/Android/MainApplication.cs +++ b/src/Android/MainApplication.cs @@ -1,6 +1,13 @@ using System; +using System.IO; using Android.App; using Android.Runtime; +using Bit.App.Abstractions; +using Bit.App.Services; +using Bit.Core.Abstractions; +using Bit.Core.Services; +using Bit.Core.Utilities; +using Bit.Droid.Services; namespace Bit.Droid { @@ -14,12 +21,34 @@ namespace Bit.Droid { public MainApplication(IntPtr handle, JniHandleOwnership transer) : base(handle, transer) - { } + { + if(ServiceContainer.RegisteredServices.Count == 0) + { + RegisterLocalServices(); + ServiceContainer.Init(); + } + } public override void OnCreate() { base.OnCreate(); Plugin.CurrentActivity.CrossCurrentActivity.Current.Init(this); } + + public void RegisterLocalServices() + { + var preferencesStorage = new PreferencesStorageService(null); + var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); + var liteDbStorage = new LiteDbStorageService(Path.Combine(documentsPath, "bitwarden.db")); + var deviceActionService = new DeviceActionService(); + + ServiceContainer.Register("cryptoPrimitiveService", new CryptoPrimitiveService()); + ServiceContainer.Register("storageService", + new MobileStorageService(preferencesStorage, liteDbStorage)); + ServiceContainer.Register("secureStorageService", new SecureStorageService()); + ServiceContainer.Register("deviceActionService", deviceActionService); + ServiceContainer.Register("platformUtilsService", + new MobilePlatformUtilsService(deviceActionService)); + } } } \ No newline at end of file diff --git a/src/Core/Services/AppIdService.cs b/src/Core/Services/AppIdService.cs index d5210ee09..a0207bf5f 100644 --- a/src/Core/Services/AppIdService.cs +++ b/src/Core/Services/AppIdService.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; namespace Bit.Core.Services { - public class AppIdService + public class AppIdService : IAppIdService { private readonly IStorageService _storageService; diff --git a/src/Core/Services/PclCryptoFunctionService.cs b/src/Core/Services/PclCryptoFunctionService.cs index 19e3470b1..325d878d5 100644 --- a/src/Core/Services/PclCryptoFunctionService.cs +++ b/src/Core/Services/PclCryptoFunctionService.cs @@ -8,7 +8,7 @@ using static PCLCrypto.WinRTCrypto; namespace Bit.Core.Services { - public class PclCryptoFunctionService + public class PclCryptoFunctionService : ICryptoFunctionService { private readonly ICryptoPrimitiveService _cryptoPrimitiveService; diff --git a/src/Core/Utilities/ServiceContainer.cs b/src/Core/Utilities/ServiceContainer.cs new file mode 100644 index 000000000..e9d276aed --- /dev/null +++ b/src/Core/Utilities/ServiceContainer.cs @@ -0,0 +1,66 @@ +using Bit.Core.Abstractions; +using Bit.Core.Services; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Bit.Core.Utilities +{ + public static class ServiceContainer + { + public static Dictionary RegisteredServices { get; set; } = new Dictionary(); + public static bool Inited { get; set; } + + public static void Init() + { + if(Inited) + { + return; + } + Inited = true; + + var platformUtilsService = Resolve("platformUtilsService"); + var storageService = Resolve("storageService"); + var secureStorageService = Resolve("secureStorageService"); + var cryptoPrimitiveService = Resolve("cryptoPrimitiveService"); + + var stateService = new StateService(); + var cryptoFunctionService = new PclCryptoFunctionService(cryptoPrimitiveService); + var cryptoService = new CryptoService(storageService, secureStorageService, cryptoFunctionService); + var tokenService = new TokenService(storageService); + var apiService = new ApiService(tokenService, platformUtilsService, (bool expired) => Task.FromResult(0)); + var appIdService = new AppIdService(storageService); + var userService = new UserService(storageService, tokenService); + + Register("stateService", stateService); + Register("cryptoFunctionService", cryptoFunctionService); + Register("cryptoService", cryptoService); + Register("tokenService", tokenService); + Register("apiService", apiService); // TODO: interface + Register("appIdService", appIdService); + Register("userService", userService); + } + + public static void Register(string serviceName, T obj) + { + if(RegisteredServices.ContainsKey(serviceName)) + { + throw new Exception($"Service {serviceName} has already been registered."); + } + RegisteredServices.Add(serviceName, obj); + } + + public static T Resolve(string serviceName, bool dontThrow = false) + { + if(RegisteredServices.ContainsKey(serviceName)) + { + return (T)RegisteredServices[serviceName]; + } + if(dontThrow) + { + return (T)(object)null; + } + throw new Exception($"Service {serviceName} is not registered."); + } + } +}