From f208e2d0b69342dcfb6ff7bbb36322ad13910089 Mon Sep 17 00:00:00 2001 From: Geoffroy BONNEVILLE Date: Tue, 24 Mar 2020 17:31:34 +0100 Subject: [PATCH] Correct package version installed Dependency injection works Project renaming WIP replacement of services with CQRS --- ....Application.csproj => Application.csproj} | 9 ++- .../ApplicationModule.cs | 32 ++++++++++ .../Common/Interfaces/IDatabaseProxy.cs | 1 + .../Common/Interfaces/ISettingsProxy.cs | 2 +- .../Common/Mappings/MappingProfile.cs | 10 +-- .../CloseDatabase/CloseDatabaseCommand.cs | 8 +-- .../CreateDatabase/CreateDatabaseCommand.cs | 8 +-- .../SaveDatabase/SaveDatabaseCommand.cs | 15 +++-- .../Queries/GetDatabase/GetDatabaseQuery.cs | 29 +++++++++ .../IsDatabaseOpen/IsDatabaseOpenQuery.cs | 10 +-- .../Queries/OpenDatabase/OpenDatabaseQuery.cs | 6 +- .../DependencyInjection.cs | 21 +++++++ ModernKeePass.Application/project.json | 10 ++- ...ernKeePass.Domain.csproj => Domain.csproj} | 0 ModernKeePass.Domain/project.json | 2 +- .../DependencyInjection.cs | 26 ++++---- ...structure.csproj => Infrastructure.csproj} | 10 +-- .../InfrastructureModule.cs | 25 ++++++++ .../KeePass/EntryMappingProfile.cs | 3 +- .../KeePass/KeePassDatabaseClient.cs | 16 +++-- .../KeePass/KeePassPasswordClient.cs | 4 +- .../UWP/UwpSettingsClient.cs | 2 +- ModernKeePass.Infrastructure/project.json | 4 +- ModernKeePass.sln | 8 +-- ModernKeePass/App.xaml.cs | 51 ++++++++++++--- .../Exceptions/NavigationException.cs | 11 ---- ModernKeePass/Exceptions/SaveException.cs | 14 ----- ModernKeePass/Interfaces/IDatabaseService.cs | 2 +- ModernKeePass/Services/DatabaseService.cs | 6 +- ModernKeePass/ViewModels/EntryVm.cs | 2 +- .../CompositeKeyUserControl.xaml.cs | 4 +- ...dernKeePass.App.csproj => Win81App.csproj} | 62 ++++++++++++++----- ModernKeePass/packages.config | 17 ++++- .../ModernKeePass.AppTest.csproj | 4 +- 34 files changed, 310 insertions(+), 124 deletions(-) rename ModernKeePass.Application/{ModernKeePass.Application.csproj => Application.csproj} (94%) create mode 100644 ModernKeePass.Application/ApplicationModule.cs create mode 100644 ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs create mode 100644 ModernKeePass.Application/DependencyInjection.cs rename ModernKeePass.Domain/{ModernKeePass.Domain.csproj => Domain.csproj} (100%) rename ModernKeePass.Infrastructure/{ModernKeePass.Infrastructure.csproj => Infrastructure.csproj} (92%) create mode 100644 ModernKeePass.Infrastructure/InfrastructureModule.cs delete mode 100644 ModernKeePass/Exceptions/NavigationException.cs delete mode 100644 ModernKeePass/Exceptions/SaveException.cs rename ModernKeePass/{ModernKeePass.App.csproj => Win81App.csproj} (89%) diff --git a/ModernKeePass.Application/ModernKeePass.Application.csproj b/ModernKeePass.Application/Application.csproj similarity index 94% rename from ModernKeePass.Application/ModernKeePass.Application.csproj rename to ModernKeePass.Application/Application.csproj index e90d893..89aab33 100644 --- a/ModernKeePass.Application/ModernKeePass.Application.csproj +++ b/ModernKeePass.Application/Application.csproj @@ -39,6 +39,7 @@ + @@ -52,16 +53,18 @@ - + + + @@ -88,9 +91,9 @@ - + {9a0759f1-9069-4841-99e3-3bec44e17356} - ModernKeePass.Domain + Domain diff --git a/ModernKeePass.Application/ApplicationModule.cs b/ModernKeePass.Application/ApplicationModule.cs new file mode 100644 index 0000000..df6a8fc --- /dev/null +++ b/ModernKeePass.Application/ApplicationModule.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using Autofac; +using AutoMapper; +using MediatR; +using ModernKeePass.Application.Common.Mappings; +using Module = Autofac.Module; + +namespace ModernKeePass.Application +{ + public class ApplicationModule: Module + { + protected override void Load(ContainerBuilder builder) + { + // Register Automapper profiles + builder.RegisterType().As(); + + // Register Mediatr + builder + .RegisterType() + .As() + .InstancePerLifetimeScope(); + + // request & notification handlers + builder.Register(context => + { + var c = context.Resolve(); + return t => c.Resolve(t); + }); + builder.RegisterAssemblyTypes(typeof(ApplicationModule).GetTypeInfo().Assembly).AsImplementedInterfaces(); + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs index de508b7..53c5252 100644 --- a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs +++ b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs @@ -7,6 +7,7 @@ namespace ModernKeePass.Application.Common.Interfaces public interface IDatabaseProxy { bool IsOpen { get; } + string Name { get; } GroupEntity RecycleBin { get; set; } BaseEntity Cipher { get; set; } BaseEntity KeyDerivation { get; set; } diff --git a/ModernKeePass.Application/Common/Interfaces/ISettingsProxy.cs b/ModernKeePass.Application/Common/Interfaces/ISettingsProxy.cs index 6471175..05cf745 100644 --- a/ModernKeePass.Application/Common/Interfaces/ISettingsProxy.cs +++ b/ModernKeePass.Application/Common/Interfaces/ISettingsProxy.cs @@ -2,7 +2,7 @@ { public interface ISettingsProxy { - T GetSetting(string property, T defaultValue = default); + T GetSetting(string property, T defaultValue = default(T)); void PutSetting(string property, T value); } } \ No newline at end of file diff --git a/ModernKeePass.Application/Common/Mappings/MappingProfile.cs b/ModernKeePass.Application/Common/Mappings/MappingProfile.cs index c572745..00945bd 100644 --- a/ModernKeePass.Application/Common/Mappings/MappingProfile.cs +++ b/ModernKeePass.Application/Common/Mappings/MappingProfile.cs @@ -9,20 +9,20 @@ namespace ModernKeePass.Application.Common.Mappings { public MappingProfile() { - ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly()); + ApplyMappingsFromAssembly(typeof(MappingProfile).GetTypeInfo().Assembly); } private void ApplyMappingsFromAssembly(Assembly assembly) { - var types = assembly.GetExportedTypes() - .Where(t => t.GetInterfaces().Any(i => - i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>))) + var types = assembly.ExportedTypes + .Where(t => t.GetTypeInfo().ImplementedInterfaces.Any(i => + i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>))) .ToList(); foreach (var type in types) { var instance = Activator.CreateInstance(type); - var methodInfo = type.GetMethod("Mapping"); + var methodInfo = type.GetTypeInfo().GetDeclaredMethod("Mapping"); methodInfo?.Invoke(instance, new object[] { this }); } } diff --git a/ModernKeePass.Application/Database/Commands/CloseDatabase/CloseDatabaseCommand.cs b/ModernKeePass.Application/Database/Commands/CloseDatabase/CloseDatabaseCommand.cs index 904641e..c591a87 100644 --- a/ModernKeePass.Application/Database/Commands/CloseDatabase/CloseDatabaseCommand.cs +++ b/ModernKeePass.Application/Database/Commands/CloseDatabase/CloseDatabaseCommand.cs @@ -1,5 +1,4 @@ using MediatR; -using System.Threading; using System.Threading.Tasks; using ModernKeePass.Application.Common.Interfaces; using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; @@ -9,7 +8,7 @@ namespace ModernKeePass.Application.Database.Commands.CloseDatabase { public class CloseDatabaseCommand: IRequest { - public class CloseDatabaseCommandHandler : IRequestHandler + public class CloseDatabaseCommandHandler : IAsyncRequestHandler { private readonly IDatabaseProxy _database; private readonly IMediator _mediator; @@ -19,10 +18,9 @@ namespace ModernKeePass.Application.Database.Commands.CloseDatabase _database = database; _mediator = mediator; } - - public async Task Handle(CloseDatabaseCommand message, CancellationToken cancellationToken) + public async Task Handle(CloseDatabaseCommand message) { - var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery(), cancellationToken); + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); if (isDatabaseOpen) _database.CloseDatabase(); else throw new DatabaseClosedException(); } diff --git a/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs b/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs index e0e7c44..c61eb9f 100644 --- a/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs +++ b/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs @@ -1,5 +1,4 @@ using MediatR; -using System.Threading; using System.Threading.Tasks; using AutoMapper; using ModernKeePass.Application.Common.Interfaces; @@ -16,7 +15,7 @@ namespace ModernKeePass.Application.Database.Commands.CreateDatabase public FileInfo FileInfo { get; set; } public Credentials Credentials { get; set; } - public class CreateDatabaseCommandHandler : IRequestHandler + public class CreateDatabaseCommandHandler : IAsyncRequestHandler { private readonly IDatabaseProxy _database; private readonly IMediator _mediator; @@ -29,9 +28,9 @@ namespace ModernKeePass.Application.Database.Commands.CreateDatabase _mapper = mapper; } - public async Task Handle(CreateDatabaseCommand message, CancellationToken cancellationToken) + public async Task Handle(CreateDatabaseCommand message) { - var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery(), cancellationToken); + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); if (isDatabaseOpen) throw new DatabaseOpenException(); var database = await _database.Create(message.FileInfo, message.Credentials); @@ -43,6 +42,7 @@ namespace ModernKeePass.Application.Database.Commands.CreateDatabase }; return databaseVm; } + } } } \ No newline at end of file diff --git a/ModernKeePass.Application/Database/Commands/SaveDatabase/SaveDatabaseCommand.cs b/ModernKeePass.Application/Database/Commands/SaveDatabase/SaveDatabaseCommand.cs index 3d29159..e4200fa 100644 --- a/ModernKeePass.Application/Database/Commands/SaveDatabase/SaveDatabaseCommand.cs +++ b/ModernKeePass.Application/Database/Commands/SaveDatabase/SaveDatabaseCommand.cs @@ -3,13 +3,16 @@ using System.Threading; using System.Threading.Tasks; using ModernKeePass.Application.Common.Interfaces; using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Domain.Dtos; using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Database.Commands.SaveDatabase { public class SaveDatabaseCommand : IRequest { - public class SaveDatabaseCommandHandler : IRequestHandler + public FileInfo FileInfo { get; set; } + + public class SaveDatabaseCommandHandler : IAsyncRequestHandler { private readonly IDatabaseProxy _database; private readonly IMediator _mediator; @@ -20,10 +23,14 @@ namespace ModernKeePass.Application.Database.Commands.SaveDatabase _mediator = mediator; } - public async Task Handle(SaveDatabaseCommand message, CancellationToken cancellationToken) + public async Task Handle(SaveDatabaseCommand message) { - var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery(), cancellationToken); - if (isDatabaseOpen) await _database.SaveDatabase(); + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (isDatabaseOpen) + { + if (message.FileInfo != null) await _database.SaveDatabase(message.FileInfo); + else await _database.SaveDatabase(); + } else throw new DatabaseClosedException(); } } diff --git a/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs b/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs new file mode 100644 index 0000000..259b73d --- /dev/null +++ b/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs @@ -0,0 +1,29 @@ +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Models; + +namespace ModernKeePass.Application.Database.Queries.GetDatabase +{ + public class GetDatabaseQuery: IRequest + { + public class GetDatabaseQueryHandler : IRequestHandler + { + private readonly IDatabaseProxy _databaseProxy; + + public GetDatabaseQueryHandler(IDatabaseProxy databaseProxy) + { + _databaseProxy = databaseProxy; + } + + public DatabaseVm Handle(GetDatabaseQuery request) + { + var database = new DatabaseVm + { + IsOpen = _databaseProxy.IsOpen, + Name = _databaseProxy.Name + }; + return database; + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Database/Queries/IsDatabaseOpen/IsDatabaseOpenQuery.cs b/ModernKeePass.Application/Database/Queries/IsDatabaseOpen/IsDatabaseOpenQuery.cs index 0266666..32d765e 100644 --- a/ModernKeePass.Application/Database/Queries/IsDatabaseOpen/IsDatabaseOpenQuery.cs +++ b/ModernKeePass.Application/Database/Queries/IsDatabaseOpen/IsDatabaseOpenQuery.cs @@ -1,6 +1,4 @@ -using System.Threading; -using System.Threading.Tasks; -using MediatR; +using MediatR; using ModernKeePass.Application.Common.Interfaces; namespace ModernKeePass.Application.Database.Queries.IsDatabaseOpen @@ -15,10 +13,12 @@ namespace ModernKeePass.Application.Database.Queries.IsDatabaseOpen { _databaseProxy = databaseProxy; } - public Task Handle(IsDatabaseOpenQuery request, CancellationToken cancellationToken) + + public bool Handle(IsDatabaseOpenQuery message) { - return Task.FromResult(_databaseProxy.IsOpen); + return _databaseProxy.IsOpen; } + } } } \ No newline at end of file diff --git a/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs b/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs index 0fd8917..4febd77 100644 --- a/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs +++ b/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs @@ -16,7 +16,7 @@ namespace ModernKeePass.Application.Database.Queries.OpenDatabase public FileInfo FileInfo { get; set; } public Credentials Credentials { get; set; } - public class OpenDatabaseQueryHandler : IRequestHandler + public class OpenDatabaseQueryHandler : IAsyncRequestHandler { private readonly IMapper _mapper; private readonly IMediator _mediator; @@ -29,9 +29,9 @@ namespace ModernKeePass.Application.Database.Queries.OpenDatabase _databaseProxy = databaseProxy; } - public async Task Handle(OpenDatabaseQuery request, CancellationToken cancellationToken) + public async Task Handle(OpenDatabaseQuery request) { - var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery(), cancellationToken); + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); if (isDatabaseOpen) throw new DatabaseOpenException(); var database = await _databaseProxy.Open(request.FileInfo, request.Credentials); diff --git a/ModernKeePass.Application/DependencyInjection.cs b/ModernKeePass.Application/DependencyInjection.cs new file mode 100644 index 0000000..0b9a065 --- /dev/null +++ b/ModernKeePass.Application/DependencyInjection.cs @@ -0,0 +1,21 @@ +using System.Reflection; +using AutoMapper; +using FluentValidation; +using MediatR; +using Microsoft.Extensions.DependencyInjection; + +namespace ModernKeePass.Application +{ + public static class DependencyInjection + { + public static IServiceCollection AddApplication(this IServiceCollection services) + { + var assembly = typeof(DependencyInjection).GetTypeInfo().Assembly; + services.AddAutoMapper(assembly); + services.AddMediatR(assembly); + //services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly()); + + return services; + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/project.json b/ModernKeePass.Application/project.json index 1118a9b..3af741f 100644 --- a/ModernKeePass.Application/project.json +++ b/ModernKeePass.Application/project.json @@ -2,11 +2,15 @@ "supports": {}, "dependencies": { "Autofac": "4.9.4", - "AutoMapper": "6.2.2", + "Autofac.Extensions.DependencyInjection": "4.4.0", + "AutoMapper": "6.1.1", + "AutoMapper.Extensions.Microsoft.DependencyInjection": "2.0.1", "FluentValidation": "8.6.2", - "MediatR": "4.0.0", + "MediatR": "3.0.1", + "MediatR.Extensions.Microsoft.DependencyInjection": "2.0.0", + "Microsoft.Extensions.DependencyInjection": "1.1.1", "Microsoft.NETCore.Portable.Compatibility": "1.0.1", - "NETStandard.Library": "1.6.1", + "NETStandard.Library": "2.0.3", "Splat": "3.0.0" }, "frameworks": { diff --git a/ModernKeePass.Domain/ModernKeePass.Domain.csproj b/ModernKeePass.Domain/Domain.csproj similarity index 100% rename from ModernKeePass.Domain/ModernKeePass.Domain.csproj rename to ModernKeePass.Domain/Domain.csproj diff --git a/ModernKeePass.Domain/project.json b/ModernKeePass.Domain/project.json index 942ec30..7455ea7 100644 --- a/ModernKeePass.Domain/project.json +++ b/ModernKeePass.Domain/project.json @@ -2,7 +2,7 @@ "supports": {}, "dependencies": { "Microsoft.NETCore.Portable.Compatibility": "1.0.1", - "NETStandard.Library": "1.6.1", + "NETStandard.Library": "2.0.3", "Splat": "3.0.0" }, "frameworks": { diff --git a/ModernKeePass.Infrastructure/DependencyInjection.cs b/ModernKeePass.Infrastructure/DependencyInjection.cs index bbebb55..9c2110d 100644 --- a/ModernKeePass.Infrastructure/DependencyInjection.cs +++ b/ModernKeePass.Infrastructure/DependencyInjection.cs @@ -1,25 +1,27 @@ -using Autofac; +using System.Reflection; using AutoMapper; +using Microsoft.Extensions.DependencyInjection; using ModernKeePass.Application.Common.Interfaces; using ModernKeePass.Infrastructure.KeePass; using ModernKeePass.Infrastructure.UWP; namespace ModernKeePass.Infrastructure { - public class DependencyInjection: Module + public static class DependencyInjection { - protected override void Load(ContainerBuilder builder) + public static IServiceCollection AddInfrastructure(this IServiceCollection services) { - builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As(); + var assembly = typeof(DependencyInjection).GetTypeInfo().Assembly; + services.AddAutoMapper(assembly); - // Register Automapper profiles - builder.RegisterType().As(); + services.AddSingleton(typeof(IDatabaseProxy), typeof(KeePassDatabaseClient)); + services.AddTransient(typeof(ICryptographyClient), typeof(KeePassCryptographyClient)); + services.AddTransient(typeof(IPasswordProxy), typeof(KeePassPasswordClient)); + services.AddTransient(typeof(IResourceProxy), typeof(UwpResourceClient)); + services.AddTransient(typeof(ISettingsProxy), typeof(UwpSettingsClient)); + services.AddTransient(typeof(IRecentProxy), typeof(UwpRecentFilesClient)); + services.AddTransient(typeof(IFileProxy), typeof(StorageFileClient)); + return services; } } } \ No newline at end of file diff --git a/ModernKeePass.Infrastructure/ModernKeePass.Infrastructure.csproj b/ModernKeePass.Infrastructure/Infrastructure.csproj similarity index 92% rename from ModernKeePass.Infrastructure/ModernKeePass.Infrastructure.csproj rename to ModernKeePass.Infrastructure/Infrastructure.csproj index bac34e7..8dae871 100644 --- a/ModernKeePass.Infrastructure/ModernKeePass.Infrastructure.csproj +++ b/ModernKeePass.Infrastructure/Infrastructure.csproj @@ -41,6 +41,7 @@ + @@ -54,19 +55,20 @@ - + {42353562-5e43-459c-8e3e-2f21e575261d} - ModernKeePass.Application + Application - + {9a0759f1-9069-4841-99e3-3bec44e17356} - ModernKeePass.Domain + Domain False Libs\Windows.winmd + False diff --git a/ModernKeePass.Infrastructure/InfrastructureModule.cs b/ModernKeePass.Infrastructure/InfrastructureModule.cs new file mode 100644 index 0000000..c479d57 --- /dev/null +++ b/ModernKeePass.Infrastructure/InfrastructureModule.cs @@ -0,0 +1,25 @@ +using Autofac; +using AutoMapper; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Infrastructure.KeePass; +using ModernKeePass.Infrastructure.UWP; + +namespace ModernKeePass.Infrastructure +{ + public class InfrastructureModule: Module + { + protected override void Load(ContainerBuilder builder) + { + builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + + // Register Automapper profiles + builder.RegisterType().As(); + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Infrastructure/KeePass/EntryMappingProfile.cs b/ModernKeePass.Infrastructure/KeePass/EntryMappingProfile.cs index a767cf9..916b250 100644 --- a/ModernKeePass.Infrastructure/KeePass/EntryMappingProfile.cs +++ b/ModernKeePass.Infrastructure/KeePass/EntryMappingProfile.cs @@ -17,6 +17,7 @@ namespace ModernKeePass.Infrastructure.KeePass private void FromDtoToModel() { + Uri url; CreateMap() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Uuid.ToHexString())) .ForMember(dest => dest.Name, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.TitleField))) @@ -24,7 +25,7 @@ namespace ModernKeePass.Infrastructure.KeePass .ForMember(dest => dest.Password, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.PasswordField))) .ForMember(dest => dest.Url, opt => { - opt.PreCondition(src => Uri.TryCreate(GetEntryValue(src, PwDefs.UrlField), UriKind.Absolute, out _)); + opt.PreCondition(src => Uri.TryCreate(GetEntryValue(src, PwDefs.UrlField), UriKind.Absolute, out url)); opt.MapFrom(src => new Uri(GetEntryValue(src, PwDefs.UrlField))); }) .ForMember(dest => dest.Notes, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.NotesField))) diff --git a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs index 47aff20..9e7143e 100644 --- a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs +++ b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs @@ -26,6 +26,7 @@ namespace ModernKeePass.Infrastructure.KeePass private CompositeKey _compositeKey; public bool IsOpen => (_pwDatabase?.IsOpen).GetValueOrDefault(); + public string Name => _pwDatabase?.Name; public GroupEntity RecycleBin { get; set; } @@ -40,7 +41,7 @@ namespace ModernKeePass.Infrastructure.KeePass Name = cipher.DisplayName }; } - set => _pwDatabase.DataCipherUuid = BuildIdFromString(value.Id); + set { _pwDatabase.DataCipherUuid = BuildIdFromString(value.Id); } } public BaseEntity KeyDerivation @@ -53,15 +54,18 @@ namespace ModernKeePass.Infrastructure.KeePass Id = keyDerivation.Uuid.ToHexString(), Name = keyDerivation.Name }; - } - set => _pwDatabase.KdfParameters = KdfPool.Engines - .FirstOrDefault(e => e.Uuid.Equals(BuildIdFromString(value.Name)))?.GetDefaultParameters(); + } + set + { + _pwDatabase.KdfParameters = KdfPool.Engines + .FirstOrDefault(e => e.Uuid.Equals(BuildIdFromString(value.Name)))?.GetDefaultParameters(); + } } public string Compression { - get => _pwDatabase.Compression.ToString("G"); - set => _pwDatabase.Compression = (PwCompressionAlgorithm)Enum.Parse(typeof(PwCompressionAlgorithm), value); + get { return _pwDatabase.Compression.ToString("G"); } + set { _pwDatabase.Compression = (PwCompressionAlgorithm) Enum.Parse(typeof(PwCompressionAlgorithm), value); } } public KeePassDatabaseClient(ISettingsProxy settings, IFileProxy fileService, IMapper mapper) diff --git a/ModernKeePass.Infrastructure/KeePass/KeePassPasswordClient.cs b/ModernKeePass.Infrastructure/KeePass/KeePassPasswordClient.cs index 199ae47..7f846c3 100644 --- a/ModernKeePass.Infrastructure/KeePass/KeePassPasswordClient.cs +++ b/ModernKeePass.Infrastructure/KeePass/KeePassPasswordClient.cs @@ -3,6 +3,7 @@ using ModernKeePass.Domain.Dtos; using ModernKeePassLib.Cryptography; using ModernKeePassLib.Cryptography.PasswordGenerator; using ModernKeePassLib.Keys; +using ModernKeePassLib.Security; namespace ModernKeePass.Infrastructure.KeePass { @@ -28,7 +29,8 @@ namespace ModernKeePass.Infrastructure.KeePass pwProfile.CharSet.Add(options.CustomChars); - PwGenerator.Generate(out var password, pwProfile, null, new CustomPwGeneratorPool()); + ProtectedString password; + PwGenerator.Generate(out password, pwProfile, null, new CustomPwGeneratorPool()); return password.ReadString(); } diff --git a/ModernKeePass.Infrastructure/UWP/UwpSettingsClient.cs b/ModernKeePass.Infrastructure/UWP/UwpSettingsClient.cs index 612f1d7..48520f2 100644 --- a/ModernKeePass.Infrastructure/UWP/UwpSettingsClient.cs +++ b/ModernKeePass.Infrastructure/UWP/UwpSettingsClient.cs @@ -9,7 +9,7 @@ namespace ModernKeePass.Infrastructure.UWP { private readonly IPropertySet _values = ApplicationData.Current.LocalSettings.Values; - public T GetSetting(string property, T defaultValue = default) + public T GetSetting(string property, T defaultValue = default(T)) { try { diff --git a/ModernKeePass.Infrastructure/project.json b/ModernKeePass.Infrastructure/project.json index 450d6f3..5b920fc 100644 --- a/ModernKeePass.Infrastructure/project.json +++ b/ModernKeePass.Infrastructure/project.json @@ -1,9 +1,11 @@ { "supports": {}, "dependencies": { + "AutoMapper": "6.1.1", + "AutoMapper.Extensions.Microsoft.DependencyInjection": "2.0.1", "Microsoft.NETCore.Portable.Compatibility": "1.0.1", "ModernKeePassLib": "2.44.1", - "NETStandard.Library": "1.6.1" + "NETStandard.Library": "2.0.3" }, "frameworks": { "netstandard1.2": {} diff --git a/ModernKeePass.sln b/ModernKeePass.sln index e1f0c0b..16a35b8 100644 --- a/ModernKeePass.sln +++ b/ModernKeePass.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.App", "ModernKeePass\ModernKeePass.App.csproj", "{A0CFC681-769B-405A-8482-0CDEE595A91F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Win81App", "ModernKeePass\Win81App.csproj", "{A0CFC681-769B-405A-8482-0CDEE595A91F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.AppTest", "ModernKeePassApp.Test\ModernKeePass.AppTest.csproj", "{7E80F5E7-724A-4668-9333-B10F5D75C6D0}" EndProject @@ -20,11 +20,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0B30588B-07B EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "presentation", "presentation", "{C7DB9A6F-77A8-4FE5-83CB-9C11F7100647}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.Application", "ModernKeePass.Application\ModernKeePass.Application.csproj", "{42353562-5E43-459C-8E3E-2F21E575261D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "ModernKeePass.Application\Application.csproj", "{42353562-5E43-459C-8E3E-2F21E575261D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.Domain", "ModernKeePass.Domain\ModernKeePass.Domain.csproj", "{9A0759F1-9069-4841-99E3-3BEC44E17356}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "ModernKeePass.Domain\Domain.csproj", "{9A0759F1-9069-4841-99E3-3BEC44E17356}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.Infrastructure", "ModernKeePass.Infrastructure\ModernKeePass.Infrastructure.csproj", "{09577E4C-4899-45B9-BF80-1803D617CCAE}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "ModernKeePass.Infrastructure\Infrastructure.csproj", "{09577E4C-4899-45B9-BF80-1803D617CCAE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/ModernKeePass/App.xaml.cs b/ModernKeePass/App.xaml.cs index f5c009e..153616b 100644 --- a/ModernKeePass/App.xaml.cs +++ b/ModernKeePass/App.xaml.cs @@ -5,13 +5,22 @@ using System.Threading.Tasks; using Windows.ApplicationModel; using Windows.ApplicationModel.Activation; using Windows.Storage; +using Windows.Storage.AccessCache; using Windows.Storage.Pickers; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; +using MediatR; +using Microsoft.Extensions.DependencyInjection; using Microsoft.HockeyApp; +using ModernKeePass.Application; +using ModernKeePass.Application.Database.Commands.CloseDatabase; +using ModernKeePass.Application.Database.Commands.SaveDatabase; +using ModernKeePass.Application.Database.Queries.GetDatabase; using ModernKeePass.Common; -using ModernKeePass.Exceptions; +using ModernKeePass.Domain.Dtos; +using ModernKeePass.Domain.Exceptions; +using ModernKeePass.Infrastructure; using ModernKeePass.Services; using ModernKeePass.Views; @@ -24,6 +33,10 @@ namespace ModernKeePass /// sealed partial class App { + public IServiceProvider Services { get; } + + private IMediator _mediator; + /// /// Initializes the singleton application object. This is the first line of authored code /// executed, and as such is the logical equivalent of main() or WinMain(). @@ -39,6 +52,13 @@ namespace ModernKeePass Suspending += OnSuspending; Resuming += OnResuming; UnhandledException += OnUnhandledException; + + // Setup DI + IServiceCollection serviceCollection = new ServiceCollection(); + serviceCollection.AddApplication(); + serviceCollection.AddInfrastructure(); + Services = serviceCollection.BuildServiceProvider(); + _mediator = Services.GetService(); } #region Event Handlers @@ -52,8 +72,7 @@ namespace ModernKeePass exception.InnerException != null ? exception.InnerException : exception; - - var database = DatabaseService.Instance; + var resource = new ResourcesService(); if (realException is SaveException) { @@ -64,6 +83,7 @@ namespace ModernKeePass resource.GetResourceValue("MessageDialogSaveErrorButtonDiscard"), async command => { + var database = await _mediator.Send(new GetDatabaseQuery()); var savePicker = new FileSavePicker { SuggestedStartLocation = PickerLocationId.DocumentsLibrary, @@ -73,7 +93,16 @@ namespace ModernKeePass new List {".kdbx"}); var file = await savePicker.PickSaveFileAsync(); - if (file != null) database.Save(file); + if (file != null) + { + var token = StorageApplicationPermissions.FutureAccessList.Add(file); + var fileInfo = new FileInfo + { + Name = file.DisplayName, + Path = token + }; + await _mediator.Send(new SaveDatabaseCommand { FileInfo = fileInfo }); + } }, null); } } @@ -136,14 +165,13 @@ namespace ModernKeePass Window.Current.Activate(); } - private void OnResuming(object sender, object e) + private async void OnResuming(object sender, object e) { var currentFrame = Window.Current.Content as Frame; - var database = DatabaseService.Instance; try { - database.ReOpen(); + var database = await _mediator.Send(new GetDatabaseQuery()); #if DEBUG ToastNotificationHelper.ShowGenericToast(database.Name, "Database reopened (changes were saved)"); #endif @@ -177,11 +205,14 @@ namespace ModernKeePass private async void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); - var database = DatabaseService.Instance; try { - if (SettingsService.Instance.GetSetting("SaveSuspend", true)) database.Save(); - database.Close(false); + var database = await _mediator.Send(new GetDatabaseQuery()); + if (SettingsService.Instance.GetSetting("SaveSuspend", true)) + { + await _mediator.Send(new SaveDatabaseCommand()); + } + await _mediator.Send(new CloseDatabaseCommand()); } catch (Exception exception) { diff --git a/ModernKeePass/Exceptions/NavigationException.cs b/ModernKeePass/Exceptions/NavigationException.cs deleted file mode 100644 index a42109f..0000000 --- a/ModernKeePass/Exceptions/NavigationException.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace ModernKeePass.Exceptions -{ - public class NavigationException: Exception - { - public NavigationException(Type pageType) : base($"Failed to load Page {pageType.FullName}") - { - } - } -} \ No newline at end of file diff --git a/ModernKeePass/Exceptions/SaveException.cs b/ModernKeePass/Exceptions/SaveException.cs deleted file mode 100644 index f24bb90..0000000 --- a/ModernKeePass/Exceptions/SaveException.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace ModernKeePass.Exceptions -{ - public class SaveException : Exception - { - public new Exception InnerException { get; } - - public SaveException(Exception exception) - { - InnerException = exception; - } - } -} diff --git a/ModernKeePass/Interfaces/IDatabaseService.cs b/ModernKeePass/Interfaces/IDatabaseService.cs index 6931207..5b4c37d 100644 --- a/ModernKeePass/Interfaces/IDatabaseService.cs +++ b/ModernKeePass/Interfaces/IDatabaseService.cs @@ -20,7 +20,7 @@ namespace ModernKeePass.Interfaces bool HasChanged { get; set; } Task Open(StorageFile databaseFile, CompositeKey key, bool createNew = false); - void ReOpen(); + Task ReOpen(); void Save(); Task Save(StorageFile file); void CreateRecycleBin(string title); diff --git a/ModernKeePass/Services/DatabaseService.cs b/ModernKeePass/Services/DatabaseService.cs index f79bbc3..6fda7af 100644 --- a/ModernKeePass/Services/DatabaseService.cs +++ b/ModernKeePass/Services/DatabaseService.cs @@ -3,7 +3,7 @@ using System.Runtime.InteropServices.WindowsRuntime; using System.Threading.Tasks; using Windows.Storage; using Microsoft.HockeyApp; -using ModernKeePass.Exceptions; +using ModernKeePass.Domain.Exceptions; using ModernKeePass.Interfaces; using ModernKeePass.ViewModels; using ModernKeePassLib; @@ -122,9 +122,9 @@ namespace ModernKeePass.Services } } - public void ReOpen() + public async Task ReOpen() { - Open(_databaseFile, _compositeKey); + await Open(_databaseFile, _compositeKey); } /// diff --git a/ModernKeePass/ViewModels/EntryVm.cs b/ModernKeePass/ViewModels/EntryVm.cs index 7978a45..b7c3414 100644 --- a/ModernKeePass/ViewModels/EntryVm.cs +++ b/ModernKeePass/ViewModels/EntryVm.cs @@ -242,7 +242,7 @@ namespace ModernKeePass.ViewModels if (UpperCasePatternSelected) pwProfile.CharSet.Add(PwCharSet.UpperCase); if (LowerCasePatternSelected) pwProfile.CharSet.Add(PwCharSet.LowerCase); if (DigitsPatternSelected) pwProfile.CharSet.Add(PwCharSet.Digits); - if (SpecialPatternSelected) pwProfile.CharSet.Add(PwCharSet.SpecialChars); + if (SpecialPatternSelected) pwProfile.CharSet.Add(PwCharSet.Special); if (MinusPatternSelected) pwProfile.CharSet.Add('-'); if (UnderscorePatternSelected) pwProfile.CharSet.Add('_'); if (SpacePatternSelected) pwProfile.CharSet.Add(' '); diff --git a/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs b/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs index a991bac..cb06e50 100644 --- a/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs +++ b/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs @@ -85,7 +85,7 @@ namespace ModernKeePass.Views.UserControls if (UpdateKey) { - Model.UpdateKey(); + await Model.UpdateKey(); ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroup)); } else @@ -157,7 +157,7 @@ namespace ModernKeePass.Views.UserControls var file = await savePicker.PickSaveFileAsync(); if (file == null) return; - Model.CreateKeyFile(file); + await Model.CreateKeyFile(file); } private async Task OpenDatabase(IResourceService resource) diff --git a/ModernKeePass/ModernKeePass.App.csproj b/ModernKeePass/Win81App.csproj similarity index 89% rename from ModernKeePass/ModernKeePass.App.csproj rename to ModernKeePass/Win81App.csproj index ac426e3..69f5709 100644 --- a/ModernKeePass/ModernKeePass.App.csproj +++ b/ModernKeePass/Win81App.csproj @@ -19,6 +19,8 @@ True neutral Always + + AnyCPU @@ -116,7 +118,6 @@ App.xaml - @@ -147,7 +148,6 @@ - @@ -393,10 +393,41 @@ + + ..\..\..\..\..\.nuget\packages\Autofac\4.9.4\lib\netstandard1.1\Autofac.dll + + + ..\packages\AutoMapper.6.1.1\lib\netstandard1.1\AutoMapper.dll + True + + + ..\packages\AutoMapper.Extensions.Microsoft.DependencyInjection.2.0.1\lib\netstandard1.1\AutoMapper.Extensions.Microsoft.DependencyInjection.dll + True + ..\packages\Portable.BouncyCastle.1.8.5\lib\netstandard1.0\BouncyCastle.Crypto.dll True + + ..\packages\FluentValidation.8.6.2\lib\netstandard1.1\FluentValidation.dll + True + + + ..\packages\MediatR.3.0.1\lib\netstandard1.1\MediatR.dll + True + + + ..\packages\MediatR.Extensions.Microsoft.DependencyInjection.2.0.0\lib\netstandard1.1\MediatR.Extensions.Microsoft.DependencyInjection.dll + True + + + ..\packages\Microsoft.Extensions.DependencyInjection.1.1.1\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll + True + + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.1\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + True + ..\packages\HockeySDK.Core.4.1.6\lib\portable-net45+win8+wp8+wpa81+win81+uap10.0\Microsoft.HockeyApp.Core45.dll True @@ -433,6 +464,14 @@ ..\packages\System.Collections.Immutable.1.5.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll True + + ..\packages\System.ComponentModel.Primitives.4.3.0\lib\netstandard1.0\System.ComponentModel.Primitives.dll + True + + + ..\packages\System.ComponentModel.TypeConverter.4.3.0\lib\netstandard1.0\System.ComponentModel.TypeConverter.dll + True + ..\packages\System.Drawing.Primitives.4.3.0\lib\netstandard1.1\System.Drawing.Primitives.dll True @@ -538,30 +577,23 @@ - + {42353562-5e43-459c-8e3e-2f21e575261d} - ModernKeePass.Application + Application - + {9a0759f1-9069-4841-99e3-3bec44e17356} - ModernKeePass.Domain + Domain - + {09577e4c-4899-45b9-bf80-1803d617ccae} - ModernKeePass.Infrastructure + Infrastructure 12.0 - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - -