-
Notifications
You must be signed in to change notification settings - Fork 42
Use IoC Container #258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use IoC Container #258
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| using AngorApp.Sections.Shell; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
|
|
||
| namespace AngorApp.Composition; | ||
|
|
||
| public static class CompositionRoot | ||
| { | ||
| public static IMainViewModel CreateMainViewModel(Control topLevelView) | ||
| { | ||
| var services = new ServiceCollection(); | ||
|
|
||
| services | ||
| .AddUIServices(topLevelView) | ||
| .AddUIModelServices() | ||
| .AddViewModels(); | ||
|
|
||
| var serviceProvider = services.BuildServiceProvider(); | ||
| return serviceProvider.GetRequiredService<IMainViewModel>(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| using AngorApp.Sections.Shell; | ||
| using AngorApp.Sections.Shell.Sections; | ||
|
|
||
| namespace AngorApp.Composition; | ||
|
|
||
| public interface ISectionsFactory | ||
| { | ||
| IEnumerable<SectionBase> CreateSections(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| using AngorApp.Core; | ||
| using AngorApp.Sections; | ||
| using AngorApp.Sections.Founder; | ||
| using AngorApp.Sections.Home; | ||
| using AngorApp.Sections.Portfolio; | ||
| using AngorApp.Sections.Shell; | ||
| using AngorApp.Sections.Shell.Sections; | ||
| using AngorApp.Sections.Wallet; | ||
| using AngorApp.UI.Services; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Separator = AngorApp.Sections.Shell.Sections.Separator; | ||
|
|
||
| namespace AngorApp.Composition; | ||
|
|
||
| public class SectionsFactory(IServiceProvider serviceProvider) : ISectionsFactory | ||
| { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what are sections exactly? is this like sections of the UI?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are the sections that appear in the Sidebar. Their have a ViewModel as content, and they are lazily loaded as needed. |
||
| public IEnumerable<SectionBase> CreateSections() | ||
| { | ||
| return new SectionBase[] | ||
| { | ||
| Section.Create("Home", Get<IHomeSectionViewModel>(), "svg:/Assets/angor-icon.svg"), | ||
| new Separator(), | ||
| Section.Create("Wallet", Get<IWalletSectionViewModel>(), "fa-wallet"), | ||
| Section.Create("Browse", Get<NavigationViewModel>(), "fa-magnifying-glass"), | ||
| Section.Create("Portfolio", Get<IPortfolioSectionViewModel>(), "fa-hand-holding-dollar"), | ||
| Section.Create("Founder", Get<IFounderSectionViewModel>(), "fa-money-bills"), | ||
| new Separator(), | ||
| Section.Create("Settings", () => new object(), "fa-gear"), | ||
| new CommandSection("Angor Hub", | ||
| ReactiveCommand.CreateFromTask(() => | ||
| Get<UIServices>()().LauncherService.LaunchUri(Constants.AngorHubUri)), | ||
| "fa-magnifying-glass") { IsPrimary = false } | ||
| }; | ||
|
|
||
| Func<T> Get<T>() where T : notnull | ||
| { | ||
| return serviceProvider.GetRequiredService<T>; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| using Angor.UI.Model; | ||
| using Angor.UI.Model.Implementation; | ||
| using Angor.UI.Model.Implementation.Projects; | ||
| using AngorApp.Core; | ||
| using AngorApp.Design; | ||
| using AngorApp.Sections; | ||
| using AngorApp.Sections.Browse; | ||
| using AngorApp.Sections.Founder; | ||
| using AngorApp.Sections.Home; | ||
| using AngorApp.Sections.Portfolio; | ||
| using AngorApp.Sections.Shell; | ||
| using AngorApp.Sections.Wallet; | ||
| using AngorApp.UI.Services; | ||
| using Avalonia.Controls.Notifications; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Zafiro.Avalonia.Controls.Navigation; | ||
| using Zafiro.Avalonia.Dialogs; | ||
| using Zafiro.Avalonia.Services; | ||
| using Zafiro.UI; | ||
|
|
||
| namespace AngorApp.Composition; | ||
|
|
||
| public static class ServiceCollectionExtensions | ||
| { | ||
| public static IServiceCollection AddUIServices(this IServiceCollection services, Control parent) | ||
| { | ||
| var topLevel = TopLevel.GetTopLevel(parent); | ||
|
|
||
| return services | ||
| .AddSingleton<ILauncherService>(_ => new LauncherService(topLevel!.Launcher)) | ||
| .AddSingleton<IDialog, DesktopDialog>() | ||
| .AddSingleton<IActiveWallet, ActiveWallet>() | ||
| .AddSingleton<INotificationService>(_ => new NotificationService( | ||
| new WindowNotificationManager(topLevel) | ||
| { | ||
| Position = NotificationPosition.BottomRight | ||
| } | ||
| )) | ||
| .AddSingleton<UIServices>(sp => new UIServices( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't all those services just get resolved automatically? why this hack?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're absolutely right. Leftover from previous code... Will fix! |
||
| sp.GetRequiredService<ILauncherService>(), | ||
| sp.GetRequiredService<IDialog>(), | ||
| sp.GetRequiredService<INotificationService>(), | ||
| sp.GetRequiredService<IActiveWallet>() | ||
| )); | ||
| } | ||
|
|
||
| public static IServiceCollection AddUIModelServices(this IServiceCollection services) | ||
| { | ||
| return services | ||
| .AddSingleton<IWalletProvider, WalletProviderDesign>() | ||
| .AddSingleton<IWalletBuilder, WalletBuilderDesign>() | ||
| .AddSingleton<IWalletFactory, WalletFactory>() | ||
| .AddSingleton<IProjectService>(sp => | ||
| { | ||
| var loggerFactory = LoggerConfig.CreateFactory(); | ||
| return new ProjectService( | ||
| DependencyFactory.GetIndexerService(loggerFactory), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. normally we do not pass the logger factory to services do we?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| DependencyFactory.GetRelayService(loggerFactory) | ||
| ); | ||
| }); | ||
| } | ||
|
|
||
| private delegate IBrowseSectionViewModel BrowseSectionViewModelFactory(INavigator navigator); | ||
|
|
||
| public static IServiceCollection AddViewModels(this IServiceCollection services) | ||
| { | ||
| return services | ||
| .AddTransient<BrowseSectionViewModelFactory>(sp => | ||
| navigator => ActivatorUtilities.CreateInstance<BrowseSectionViewModel>(sp, navigator)) | ||
| .AddTransient<NavigationViewModel>(sp => | ||
| new NavigationViewModel(navigator => | ||
| sp.GetRequiredService<BrowseSectionViewModelFactory>()(navigator) | ||
| )) | ||
| .AddSingleton<ISectionsFactory, SectionsFactory>() | ||
| .AddSingleton<Lazy<IMainViewModel>>(sp => new Lazy<IMainViewModel>(sp.GetRequiredService<IMainViewModel>)) | ||
| .AddTransient<IHomeSectionViewModel>(sp => | ||
| new HomeSectionViewModel( | ||
| sp.GetRequiredService<IActiveWallet>(), | ||
| sp.GetRequiredService<UIServices>(), | ||
| () => sp.GetRequiredService<Lazy<IMainViewModel>>().Value | ||
| )) | ||
| .AddTransient<IWalletSectionViewModel, WalletSectionViewModel>() | ||
|
|
||
| // // This registration could be maintained for alternative uses, but for navigation we will use the delegate | ||
| .AddTransient<IBrowseSectionViewModel, BrowseSectionViewModel>() | ||
| .AddTransient<IPortfolioSectionViewModel, PortfolioSectionViewModel>() | ||
| .AddTransient<IFounderSectionViewModel, FounderSectionViewModel>() | ||
| .AddSingleton<IMainViewModel>(sp => | ||
| new MainViewModel( | ||
| sp.GetRequiredService<ISectionsFactory>().CreateSections(), | ||
| sp.GetRequiredService<UIServices>() | ||
| )); | ||
| } | ||
| } | ||
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will also at some point have to add all the angor services, it is a good idea to do it this way, we can also add later a method
.AddAngorServices()