瀏覽代碼

EF model complete, fixed. Initial services and mappings

Dalibor Votruba 1 年之前
父節點
當前提交
300a4bdc52

+ 9 - 0
bundleboiler.business/GlobalSuppressions.cs

@@ -0,0 +1,9 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:qdr.app.bundleboiler.business.Services.BaseService`1.#ctor(`0,qdr.app.bundleboiler.business.IOptions,Quadarax.Foundation.Core.Logging.ILogger)")]
+[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:qdr.app.bundleboiler.business.Services.BaseService.#ctor(qdr.app.bundleboiler.business.IOptions,Quadarax.Foundation.Core.Logging.ILogger)")]

+ 74 - 0
bundleboiler.business/Services/BaseService.cs

@@ -0,0 +1,74 @@
+
+using Quadarax.Foundation.Core.Business;
+using Quadarax.Foundation.Core.Data;
+using Quadarax.Foundation.Core.Data.Interface.Repository;
+using Quadarax.Foundation.Core.Logging;
+using System.Runtime.CompilerServices;
+using System.Security.Principal;
+
+namespace qdr.app.bundleboiler.business.Services
+{
+    public abstract class BaseService<TRepository> : AbstractRepositoryService<TRepository>
+        where TRepository : IRepository
+    {
+        #region *** Properties ***
+
+        protected IOptions Options { get; }
+        #endregion
+
+        protected BaseService(TRepository repository, IOptions options, ILogger logger) : base(repository, Thread.CurrentPrincipal ?? new WindowsPrincipal(WindowsIdentity.GetAnonymous()), logger)
+        {
+            Options = options ?? throw new ArgumentNullException(nameof(options));
+        }
+
+        protected TResult Operation<TResult>(Func<TResult> operation, [CallerMemberName] string callerName = "unknown")
+            where TResult : IResult
+        {
+            var result = Result.Ok;
+            try
+            {
+
+                result = operation();
+            }
+            catch (Exception ex)
+            {
+                Log.Log(LogSeverityEnum.Fatal, $"Error during '{callerName}' operation: {ex.Message}", ex);
+                result = new Result([new Error(ex)]);
+            }
+
+            return (TResult)result;
+        }
+    }
+
+    public abstract class BaseService : AbstractService
+    {
+        #region *** Properties ***
+
+        protected IOptions Options { get; }
+        #endregion
+
+        protected BaseService(IOptions options, ILogger logger) : base(Thread.CurrentPrincipal ?? new WindowsPrincipal(WindowsIdentity.GetAnonymous()), logger)
+        {
+            Options = options ?? throw new ArgumentNullException(nameof(options));
+        }
+
+        protected TResult Operation<TResult>(Func<TResult> operation, [CallerMemberName] string callerName = "unknown")
+    where TResult : IResult
+        {
+            var result = Result.Ok;
+            try
+            {
+
+                result = operation();
+            }
+            catch (Exception ex)
+            {
+                Log.Log(LogSeverityEnum.Fatal, $"Error during '{callerName}' operation: {ex.Message}", ex);
+                result = new Result([new Error(ex)]);
+            }
+
+            return (TResult)result;
+        }
+    }
+
+}

+ 47 - 0
bundleboiler.business/Services/DatabaseService.cs

@@ -0,0 +1,47 @@
+using Microsoft.EntityFrameworkCore;
+using qdr.app.bundleboiler.business.Services.Interfaces;
+using qdr.app.bundleboiler.data.Model;
+using Quadarax.Foundation.Core.Attributes;
+using Quadarax.Foundation.Core.Data;
+using Quadarax.Foundation.Core.Data.Interface.Domain;
+using Quadarax.Foundation.Core.Logging;
+
+namespace qdr.app.bundleboiler.business.Services
+{
+    [DiModule]
+    [DiImplementsOf(typeof(IDatabaseService), LifeCycleTypeEnum.Scoped)]
+    public class DatabaseService : BaseService, IDatabaseService
+    {
+        private readonly IDomain _dbcontext;
+
+        public DatabaseService(BoilerDbContext dbcontext, IOptions options, ILogger logger) : base(options, logger)
+        {
+            _dbcontext = dbcontext ?? throw new ArgumentNullException(nameof(dbcontext));
+        }
+
+        public IResult EnsureDatabase()
+        {
+            return Operation(() =>
+            {
+                if (((DbContext)_dbcontext).Database.EnsureCreated())
+                {
+                    Log.Log(LogSeverityEnum.Info, $"Database @ '{Options.ConnectionString}' created");
+                }
+                return Result.Ok;
+            });
+
+        }
+
+        public IResult EnsureEnumerations()
+        {
+            return Operation(() =>
+            {
+                if (((DbContext)_dbcontext).Database.EnsureCreated())
+                {
+                    Log.Log(LogSeverityEnum.Info, $"Database @ '{Options.ConnectionString}' created");
+                }
+                return Result.Ok;
+            });
+        }
+    }
+}

+ 55 - 0
bundleboiler.business/Services/EnumerationService.cs

@@ -0,0 +1,55 @@
+using qdr.app.bundleboiler.business.Services.Interfaces;
+using qdr.app.bundleboiler.data.Dtos;
+using qdr.app.bundleboiler.data.Model;
+using qdr.app.bundleboiler.data.Repositories;
+using Quadarax.Foundation.Core.Attributes;
+using Quadarax.Foundation.Core.Data;
+using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
+using Quadarax.Foundation.Core.Logging;
+
+namespace qdr.app.bundleboiler.business.Services
+{
+    [DiModule]
+    [DiImplementsOf(typeof(IEnumerationService), LifeCycleTypeEnum.Scoped)]
+    public class EnumerationService : BaseService<EnumerationRepo>, IEnumerationService
+    {
+        public EnumerationService(EnumerationRepo repository, IOptions options, ILogger logger) : base(repository, options, logger)
+        {
+        }
+
+        public ResultBoolDto Contains(EnumClassType type, string code)
+        {
+            throw new NotImplementedException();
+        }
+
+        public ResultValueDto<EnumerationDto> Create(EnumerationDto dto)
+        {
+            throw new NotImplementedException();
+        }
+
+        public ResultBoolDto Delete(long id)
+        {
+            throw new NotImplementedException();
+        }
+
+        public ResultValueDto<EnumerationDto> Get(long id)
+        {
+            throw new NotImplementedException();
+        }
+
+        public ResultValueDto<EnumerationDto> Get(EnumClassType type, string code)
+        {
+            throw new NotImplementedException();
+        }
+
+        public ResultsValueDto<EnumerationDto> GetAll(IPaging page, params EnumClassType[]? classes)
+        {
+            throw new NotImplementedException();
+        }
+
+        public ResultValueDto<EnumerationDto> Update(EnumerationDto dto)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 12 - 0
bundleboiler.business/Services/Interfaces/IDatabaseService.cs

@@ -0,0 +1,12 @@
+using Quadarax.Foundation.Core.Business.Interface;
+using Quadarax.Foundation.Core.Data;
+
+
+namespace qdr.app.bundleboiler.business.Services.Interfaces
+{
+    public interface IDatabaseService : IService
+    {
+        IResult EnsureDatabase();
+        IResult EnsureEnumerations();
+    }
+}

+ 20 - 0
bundleboiler.business/Services/Interfaces/IEnumerationService.cs

@@ -0,0 +1,20 @@
+using qdr.app.bundleboiler.data.Dtos;
+using qdr.app.bundleboiler.data.Model;
+using Quadarax.Foundation.Core.Business.Interface;
+using Quadarax.Foundation.Core.Data;
+using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
+
+namespace qdr.app.bundleboiler.business.Services.Interfaces
+{
+    public interface IEnumerationService : IService
+    {
+        ResultBoolDto Contains(EnumClassType type, string code);
+        ResultValueDto<EnumerationDto> Get(long id);
+        ResultValueDto<EnumerationDto> Get(EnumClassType type, string code);
+        ResultsValueDto<EnumerationDto> GetAll(IPaging page, params EnumClassType[]? classes);
+
+        ResultValueDto<EnumerationDto> Create(EnumerationDto dto);
+        ResultValueDto<EnumerationDto> Update(EnumerationDto dto);
+        ResultBoolDto Delete(long id);
+    }
+}

+ 2 - 1
bundleboiler.business/bundleboiler.business.csproj

@@ -9,7 +9,8 @@
 
   <ItemGroup>
     <PackageReference Include="qdr.fnd.core" Version="0.0.6-alpha" />
-    <PackageReference Include="qdr.fnd.core.business" Version="0.0.4-alpha" />
+    <PackageReference Include="qdr.fnd.core.business" Version="0.0.6-alpha" />
+    <PackageReference Include="qdr.fnd.core.data.itfc" Version="0.0.4-alpha" />
   </ItemGroup>
 
   <ItemGroup>

+ 8 - 0
bundleboiler.data/DataMapper.cs

@@ -0,0 +1,8 @@
+using Quadarax.Foundation.Core.Data.Mapper;
+
+namespace qdr.app.bundleboiler.data
+{
+    public class DataMapper : Mapper<DataMapper>
+    {
+    }
+}

+ 8 - 0
bundleboiler.data/Dtos/BaseDto.cs

@@ -0,0 +1,8 @@
+using Quadarax.Foundation.Core.Data.Interface.Entity;
+
+namespace qdr.app.bundleboiler.data.Dtos
+{
+    public abstract class BaseDto : IDto
+    {
+    }
+}

+ 7 - 0
bundleboiler.data/Dtos/BaseIdDto.cs

@@ -0,0 +1,7 @@
+namespace qdr.app.bundleboiler.data.Dtos
+{
+    public abstract class BaseIdDto : BaseDto
+    {
+        public long Id { get; set; }
+    }
+}

+ 16 - 0
bundleboiler.data/Dtos/EnumerationDto.cs

@@ -0,0 +1,16 @@
+using qdr.app.bundleboiler.data.Model;
+
+namespace qdr.app.bundleboiler.data.Dtos
+{
+    public class EnumerationDto : BaseIdDto
+    {
+        public EnumClassType ClassType { get; set; }
+
+        public int OrderNo { get; set; } = 0;
+        public string Code { get; set; } = string.Empty;
+        public string Name { get; set; } = string.Empty;
+        public string? Description { get; set; }
+        public DateTime Created { get; set; }
+        public DateTime Changed { get; set; }
+    }
+}

+ 92 - 22
bundleboiler.data/Model/BoilerDbContext.cs

@@ -1,9 +1,11 @@
 using Microsoft.EntityFrameworkCore;
 using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Quadarax.Foundation.Core.Data.Domain;
+using System.Reflection.Emit;
 
 namespace qdr.app.bundleboiler.data.Model
 {
-    public class BoilerDbContext : DbContext
+    public class BoilerDbContext : DataDomain
     {
         public BoilerDbContext(DbContextOptions<BoilerDbContext> options) : base(options)
         {
@@ -30,10 +32,14 @@ namespace qdr.app.bundleboiler.data.Model
             modelBuilder.Entity<Attachment>(BuildAttachment);
             modelBuilder.Entity<AttributeCategory>(BuildAttributeCategory);
             modelBuilder.Entity<Bundle>(BuildBundle);
+            modelBuilder.Entity<BundleForkHash>(BuildBundleForkHash);
+            modelBuilder.Entity<BundleEnvironmentHash>(BuildBundleEnvironmentHash);
             modelBuilder.Entity<BundleAttribute>(BuildBundleAttribute);
             modelBuilder.Entity<Enumeration>(BuildEnumeration);
             modelBuilder.Entity<Project>(BuildProject);
             modelBuilder.Entity<Realization>(BuildRealization);
+            modelBuilder.Entity<RealizationForkHash>(BuildRealizationForkHash);
+            modelBuilder.Entity<RealizationEnvironmentHash>(BuildRealizationEnvironmentHash);
         }
 
         private void BuildActivity(EntityTypeBuilder<Activity> builder)
@@ -54,7 +60,7 @@ namespace qdr.app.bundleboiler.data.Model
             builder.Property(x => x.VersionCode).IsRequired().HasMaxLength(20);
             builder.Property(x => x.Description).HasMaxLength(500);
             builder.Property(x => x.OrderNo).IsRequired();
-            builder.HasOne(x => x.Type).WithMany().IsRequired();
+            builder.HasOne(x => x.Type).WithMany().IsRequired().OnDelete(DeleteBehavior.NoAction);
             builder.HasOne(x => x.Parent)
                    .WithMany(x => x.Artifacts)
                    .IsRequired();
@@ -104,34 +110,66 @@ namespace qdr.app.bundleboiler.data.Model
             builder.Property(x => x.VersionMajor).IsRequired();
             builder.Property(x => x.VersionMinor).IsRequired();
             builder.Property(x => x.VersionRevision).IsRequired();
-            
+
             builder.HasOne(x => x.BundleType)
                    .WithMany()
-                   .IsRequired();
-            
+                   .IsRequired().OnDelete(DeleteBehavior.NoAction);
+
             builder.HasMany(x => x.Artifacts)
                    .WithOne(x => x.Parent)
                    .IsRequired();
-            
+
             builder.HasMany(x => x.Attributes)
                    .WithOne(x => x.Owner)
                    .IsRequired();
-            
+
             builder.HasMany(x => x.Realizations)
                    .WithOne(x => x.Parent)
                    .IsRequired();
-            
+
+            builder.HasMany(r => r.Forks)
+                .WithMany()
+                .UsingEntity<BundleForkHash>();
+
             builder.HasMany(x => x.Environments)
-                   .WithMany();
-            
-            builder.HasMany(x => x.Forks)
-                   .WithMany();
-            
+                   .WithMany()
+                   .UsingEntity<BundleEnvironmentHash>();
+
             builder.HasOne(x => x.Follows)
                    .WithMany(x => x.Covers)
                    .IsRequired(false);
         }
 
+        private void BuildBundleForkHash(EntityTypeBuilder<BundleForkHash> builder)
+        {
+            builder.HasKey(rf => new { rf.BundleId, rf.EnumerationId });
+
+            builder.HasOne(rf => rf.Bundle)
+                .WithMany()
+                .HasForeignKey(rf => rf.BundleId)
+                .OnDelete(DeleteBehavior.NoAction);
+
+            builder.HasOne(rf => rf.Enumeration)
+                .WithMany()
+                .HasForeignKey(rf => rf.EnumerationId)
+                .OnDelete(DeleteBehavior.NoAction);
+        }
+
+        private void BuildBundleEnvironmentHash(EntityTypeBuilder<BundleEnvironmentHash> builder)
+        {
+            builder.HasKey(rf => new { rf.BundleId, rf.EnumerationId });
+
+            builder.HasOne(rf => rf.Bundle)
+                .WithMany()
+                .HasForeignKey(rf => rf.BundleId)
+                .OnDelete(DeleteBehavior.NoAction);
+
+            builder.HasOne(rf => rf.Enumeration)
+                .WithMany()
+                .HasForeignKey(rf => rf.EnumerationId)
+                .OnDelete(DeleteBehavior.NoAction);
+        }
+
         private void BuildBundleAttribute(EntityTypeBuilder<BundleAttribute> builder)
         {
             builder.HasKey(x => x.Id);
@@ -169,24 +207,56 @@ namespace qdr.app.bundleboiler.data.Model
             builder.HasKey(x => x.Id);
             builder.Property(x => x.Merged).IsRequired();
             builder.Property(x => x.MergedToLinkSCM).HasMaxLength(500);
-            
+
             builder.HasOne(x => x.Parent)
                    .WithMany(x => x.Realizations)
                    .IsRequired();
-            
+
             builder.HasMany(x => x.Attachments)
                    .WithOne(x => x.Parent)
-                   .IsRequired();
-            
-            builder.HasMany(x => x.Forks)
-                   .WithMany();
-            
+            .IsRequired();
+
+            builder.HasMany(r => r.Forks)
+                .WithMany()
+                .UsingEntity<RealizationForkHash>();
+
             builder.HasMany(x => x.Environments)
-                   .WithMany();
-            
+                   .WithMany()
+                   .UsingEntity<RealizationEnvironmentHash>();
+
             builder.HasOne(x => x.BundleType)
                    .WithMany()
                    .IsRequired();
         }
+
+        private void BuildRealizationForkHash(EntityTypeBuilder<RealizationForkHash> builder)
+        {
+            builder.HasKey(rf => new { rf.RealizationId, rf.EnumerationId });
+
+            builder.HasOne(rf => rf.Realization)
+                .WithMany()
+                .HasForeignKey(rf => rf.RealizationId)
+                .OnDelete(DeleteBehavior.NoAction);
+
+            builder.HasOne(rf => rf.Enumeration)
+                .WithMany()
+                .HasForeignKey(rf => rf.EnumerationId)
+                .OnDelete(DeleteBehavior.NoAction);
+        }
+
+        private void BuildRealizationEnvironmentHash(EntityTypeBuilder<RealizationEnvironmentHash> builder)
+        {
+            builder.HasKey(rf => new { rf.RealizationId, rf.EnumerationId });
+
+            builder.HasOne(rf => rf.Realization)
+                .WithMany()
+                .HasForeignKey(rf => rf.RealizationId)
+                .OnDelete(DeleteBehavior.NoAction);
+
+            builder.HasOne(rf => rf.Enumeration)
+                .WithMany()
+                .HasForeignKey(rf => rf.EnumerationId)
+                .OnDelete(DeleteBehavior.NoAction);
+        }
     }
 }

+ 11 - 0
bundleboiler.data/Model/BundleEnvironmentHash.cs

@@ -0,0 +1,11 @@
+namespace qdr.app.bundleboiler.data.Model
+{
+    public class BundleEnvironmentHash
+    {
+        public required long BundleId { get; set; }
+        public required Bundle Bundle { get; set; }
+
+        public required long EnumerationId { get; set; }
+        public required Enumeration Enumeration { get; set; }
+    }
+}

+ 17 - 0
bundleboiler.data/Model/BundleForkHash.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace qdr.app.bundleboiler.data.Model
+{
+    public class BundleForkHash
+    {
+        public required long BundleId { get; set; }
+        public required Bundle Bundle { get; set; }
+
+        public required long EnumerationId { get; set; }
+        public required Enumeration Enumeration { get; set; }
+    }
+}

+ 3 - 0
bundleboiler.data/Model/DmBaseEntity.cs

@@ -1,4 +1,5 @@
 using Quadarax.Foundation.Core.Data.Entity;
+using Quadarax.Foundation.Core.Data.Interface.Entity;
 
 namespace qdr.app.bundleboiler.data.Model
 {
@@ -12,5 +13,7 @@ namespace qdr.app.bundleboiler.data.Model
         /// The date and time the record was last changed.
         /// </summary>
         public DateTime Changed { get; set; }
+
+        protected DmBaseEntity() { }
     }
 }

+ 4 - 2
bundleboiler.data/Model/DmBaseHeadedEntity.cs

@@ -5,15 +5,17 @@
         /// <summary>
         /// The code or short code of the entity. Required.
         /// </summary>
-        public required string Code { get; set; }
+        public string Code { get; set; }
         /// <summary>
         /// The name of the entity. Required.
         /// </summary>
-        public required string Name { get; set; }
+        public string Name { get; set; }
         /// <summary>
         /// The description of the entity.
         /// </summary>
         public string? Description { get; set; }
 
+        protected DmBaseHeadedEntity() : base() { Code = string.Empty; Name = string.Empty;}
+
     }
 }

+ 4 - 1
bundleboiler.data/Model/DmEnums.cs

@@ -7,7 +7,10 @@
 
     public enum EnumClassType : int
     {
-
+        Artifact = 0,
+        Bundle = 1,
+        Environment = 3,
+        Fork = 4
 
     }
     public enum AttrClassType : int

+ 10 - 1
bundleboiler.data/Model/Enumeration.cs

@@ -1,4 +1,6 @@
-namespace qdr.app.bundleboiler.data.Model
+using Quadarax.Foundation.Core.Data.Interface.Entity;
+
+namespace qdr.app.bundleboiler.data.Model
 {
     /// <summary>
     /// Universal enumeration catalogue. Represents ordered collection of code-name values (with description), grouped by classType (means enumeration class ownership)
@@ -13,5 +15,12 @@
         /// The order number of the enumeration in the class type. Required.
         /// </summary>
         public int OrderNo { get; set; } = 0;
+
+
+        public Enumeration(): base() 
+        {
+            ClassType = default;
+            OrderNo = default;
+        }
     }
 }

+ 11 - 0
bundleboiler.data/Model/RealizationEnvironmentHash.cs

@@ -0,0 +1,11 @@
+namespace qdr.app.bundleboiler.data.Model
+{
+    public class RealizationEnvironmentHash
+    {
+        public required long RealizationId { get; set; }
+        public required Realization Realization { get; set; }
+
+        public required long EnumerationId { get; set; }
+        public required Enumeration Enumeration { get; set; }
+    }
+}

+ 11 - 0
bundleboiler.data/Model/RealizationForkHash.cs

@@ -0,0 +1,11 @@
+namespace qdr.app.bundleboiler.data.Model
+{
+    public class RealizationForkHash
+    {
+        public required long RealizationId { get; set; }
+        public required Realization Realization { get; set; }
+    
+        public required long EnumerationId { get; set; }
+        public required Enumeration Enumeration { get; set; }
+    }
+}

+ 14 - 0
bundleboiler.data/Repositories/EnumerationRepo.cs

@@ -0,0 +1,14 @@
+using qdr.app.bundleboiler.data.Model;
+using Quadarax.Foundation.Core.Data.Domain;
+using Quadarax.Foundation.Core.Data.Interface.Domain;
+using Quadarax.Foundation.Core.Data.Repository;
+
+namespace qdr.app.bundleboiler.data.Repositories
+{
+    public class EnumerationRepo : EntityRepository<long, Enumeration>
+    {
+        public EnumerationRepo(IUnitOfWork<DataDomain> unitOfWork) : base(unitOfWork)
+        {
+        }
+    }
+}

+ 2 - 1
bundleboiler.data/bundleboiler.data.csproj

@@ -9,7 +9,8 @@
 
   <ItemGroup>
     <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
-    <PackageReference Include="qdr.fnd.core.data" Version="0.0.3-alpha" />
+    <PackageReference Include="qdr.fnd.core.data" Version="0.0.4-alpha" />
+    <PackageReference Include="qdr.fnd.core.data.itfc" Version="0.0.4-alpha" />
   </ItemGroup>
 
 </Project>

+ 5 - 2
bundleboiler.ui/MainForm.cs

@@ -1,5 +1,6 @@
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
+using qdr.app.bundleboiler.business.Services.Interfaces;
 using qdr.app.bundleboiler.data.Model;
 using qdr.app.bundleboiler.ui.Configuration;
 using qdr.app.bundleboiler.ui.Dialogs;
@@ -13,13 +14,15 @@ namespace bundleboiler.ui
     {
         #region *** Private fields ***
         ILog? _log;
+        IDatabaseService _serviceDatabase;
         #endregion
 
         #region *** Constructor ***
-        public MainForm(Quadarax.Foundation.Core.Logging.ILogger? logger)
+        public MainForm(IDatabaseService? serviceDatabase, Quadarax.Foundation.Core.Logging.ILogger? logger)
         {
             InitializeComponent();
             _log = logger?.GetLogger(GetType().Name);
+            _serviceDatabase = serviceDatabase ?? throw new ArgumentNullException(nameof(serviceDatabase));
             InitializeInternal();
         }
         #endregion
@@ -31,7 +34,7 @@ namespace bundleboiler.ui
             var loggerFactory = new Quadarax.Foundation.Core.NLog.LoggerFactory();
             try
             {
-              throw new Exception("Cannot initialize application");
+                _serviceDatabase.EnsureDatabase();
             }
             catch (Exception e)
             {

+ 15 - 4
bundleboiler.ui/Program.cs

@@ -1,7 +1,11 @@
 using bundleboiler.ui;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
 using qdr.app.bundleboiler.business;
+using qdr.app.bundleboiler.business.Services.Interfaces;
+using qdr.app.bundleboiler.data;
 using qdr.app.bundleboiler.data.Model;
 using qdr.app.bundleboiler.ui.Configuration;
 using Quadarax.Foundation.Core.Business.Injection;
@@ -27,22 +31,29 @@ namespace qdr.app.bundleboiler.ui
             ServiceProvider = CreateHostBuilder().Build().Services;
 
             ApplicationConfiguration.Initialize();
-            Application.Run(new MainForm(ServiceProvider.GetService<ILogger>()));
+            Application.Run(new MainForm(ServiceProvider.GetService<IDatabaseService>(),ServiceProvider.GetService<ILogger>()));
         }
 
 
         private static IHostBuilder CreateHostBuilder()
         {
-        return Host.CreateDefaultBuilder()
+            var optionsCfg = new ApplicationOptions();
+            
+
+            return Host.CreateDefaultBuilder()
             .ConfigureServices((context, services) => {
                 // configuration
                 services.AddSingleton<IOptions, ApplicationOptions>();
                 // db context
-                services.AddDbContext<BoilerDbContext>();
+                services.AddDbContext<BoilerDbContext>(options =>
+                    options.UseSqlServer(optionsCfg.ConnectionString ?? 
+                    context.Configuration.GetConnectionString("DefaultConnection")));
+                // mapper
+                services.AddSingleton<DataMapper>();
                 // logging
                 services.AddSingleton<ILogger, Quadarax.Foundation.Core.NLog.LoggerFactory>();
                 // business services
-                DiManager.RegisterAssemblyFromThisAppdomain();
+                DiManager.RegisterAssemblyFromThisAppdomain(["bundleboiler.business", "bundleboiler.data"], Array.Empty<string>());
                 DiManager.ScanAndRegisterDependencyInjections(services);
             });
         }

+ 2 - 0
bundleboiler.ui/bundleboiler.ui.csproj

@@ -16,9 +16,11 @@
   </ItemGroup>
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
     <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
     <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0" />
     <PackageReference Include="qdr.fnd.core" Version="0.0.6-alpha" />
+    <PackageReference Include="qdr.fnd.core.business" Version="0.0.6-alpha" />
     <PackageReference Include="qdr.fnd.core.nlog" Version="0.0.4-alpha" />
   </ItemGroup>