Пример #1
0
        public async Task <ActionResult <MetadataValidationResponse> > GenerateCode()
        {
            if (!_permissionService.IsAllowed(new ActionRequestInfo(HttpContext, _implementationContainer, null, ActionTypeEnum.ManageMetadata)))
            {
                return(Unauthorized());
            }
            var bundle = await MetadataBundle.FromDbWithoutNavigations(_dbContext
                                                                       , _implementationContainer.InstanceInfo.AppTypeId, _implementationContainer.InstanceInfo.AppInstanceId);

            bundle.FixupRelationships();
            var metadataCache = new MetadataCache(bundle);
            var errorList     = await GenerateCodeValidation();

            var result = new MetadataValidationResponse();

            if (errorList.Value?.Success != true)
            {
                return(errorList);
            }

            var(succeeded, diagnostics) = await _assemblyGenerator.GenerateAssembly(metadataCache, _implementationContainer.InstanceInfo
                                                                                    , _globalConfiguration.ImplementationsDirectory, _implementationContainer.InstanceInfo.InstanceName);

            if (!succeeded)
            {
                result.Errors.AddRange(diagnostics.Select(x => x.Message));
                result.Success = false;
                return(result);
            }
            result.Success = true;
            return(result);
        }
        public async Task <ActionResult> ReleaseMetadata(ReleaseMetadataRequest request)
        {
            if (!_permissionService.IsAllowed(new ActionRequestInfo(HttpContext, _implementationContainer, null, ActionTypeEnum.ManageMetadata)))
            {
                return(Unauthorized());
            }
            var appInstance = await _dbContext.AppInstances.SingleAsync(X => X.Id == request.AppInstanceId);

            var appType = await _dbContext.AppTypes.SingleAsync(x => x.Id == appInstance.AppTypeId);

            var bundle = await MetadataBundle.FromDbWithoutNavigations(_dbContext, appType.Id, appInstance.Id);

            var json   = JsonConvert.SerializeObject(bundle);
            var zipped = TextHelper.Zip(json);

            var release = new MetadataRelease
            {
                AppTypeId            = appType.Id,
                CreatedByUserId      = 0,            //Todo: How to get this value?
                ReleaseTime          = DateTime.UtcNow,
                MetadataSnapshotText = json,
                Version     = request.Version,
                VersionCode = request.VersionCode
            };
            await _dbContext.MetadataReleases.AddAsync(release);

            if (request.SetAsInstanceMetadata)
            {
                appInstance.MetadataRelease = release;
            }
            await _dbContext.SaveChangesAsync();

            return(Ok());
        }
        public async Task <ActionResult <MetadataValidationResponse> > GenerateCode()
        {
            if (!_permissionService.IsAllowed(new ActionRequestInfo(HttpContext, _implementationContainer, null, ActionTypeEnum.ManageMetadata)))
            {
                return(Unauthorized());
            }
            var bundle = await MetadataBundle.FromDbWithoutNavigations(_dbContext
                                                                       , _implementationContainer.InstanceInfo.AppTypeId, _implementationContainer.InstanceInfo.AppInstanceId);

            bundle.FixupRelationships();
            var metadataCache = new MetadataCache(bundle);
            var errorList     = await GenerateCodeValidation();

            var result = new MetadataValidationResponse();

            if (errorList.Value?.Success != true)
            {
                return(errorList);
            }

            var r = await _assemblyGenerator.GenerateCode(metadataCache, _implementationContainer.InstanceInfo
                                                          , _globalConfiguration.ImplementationsDirectory, _implementationContainer.InstanceInfo.InstanceName);

            if (!r.Succeeded)
            {
                result.Errors.AddRange(r.Diagnostics.Select(x => x.Message));
                result.Success = false;
                return(result);
            }
            var copyFileName = _implementationContainer.InstanceInfo.InstanceSettings?.CopyAutoGeneratedEntitiesTo;

            if (!string.IsNullOrWhiteSpace(copyFileName))
            {
                try
                {
                    System.IO.File.Copy(r.SourceCodeFileName, copyFileName, true);
                }
                catch (Exception ex)
                {
                    result.Errors.Add("Could not copy source code to: " + copyFileName + "Reson: " + ex.GetFullMessage());
                }
            }
            result.Success = true;
            return(result);
        }
        public static async Task <ImplementationContainer> Create(IServiceScope scope, MetadataDbContext dbContext, int appInstanceId)
        {
            var instance = await dbContext.AppInstances.FirstOrDefaultAsync(x => x.Id == appInstanceId);

            if (instance == null)
            {
                return(null);
            }
            if (!instance.IsEnabled)
            {
                return(null);
            }
            var appType = await dbContext.AppTypes.FirstOrDefaultAsync(x => x.Id == instance.AppTypeId);

            var bundle = await MetadataBundle.FromDbWithoutNavigations(dbContext, instance.AppTypeId, instance.Id);

            bundle.FixupRelationships();
            var metadataCache = new MetadataCache(bundle);
            var metadataModel = new MetadataModel(bundle);
            var globalConfig  = scope.ServiceProvider.GetRequiredService <IOptions <GlobalConfiguration> >().Value;
            var config        = scope.ServiceProvider.GetRequiredService <IConfiguration>();
            var dataConnectionStringTemplate = config.GetConnectionString(instance.DataConnectionStringTemplateName);

            if (string.IsNullOrWhiteSpace(dataConnectionStringTemplate))
            {
                var logger = scope.ServiceProvider.GetRequiredService <ILogger <ImplementationContainer> >();
                logger.LogError($"No connection stirng named \"{instance.DataConnectionStringTemplateName}\" which is required for app instance {instance.Name}");
            }
            var lobConnectionStringTemplate = config.GetConnectionString(instance.LobConnectionStringTemplateName);

            if (string.IsNullOrWhiteSpace(lobConnectionStringTemplate))
            {
                var logger = scope.ServiceProvider.GetRequiredService <ILogger <ImplementationContainer> >();
                logger.LogError($"No connection stirng named \"{instance.LobConnectionStringTemplateName}\" which is required for app instance {instance.Name}");
            }
            InstanceSettings instanceSettings = null;

            globalConfig?.InstanceSettings?.TryGetValue(instance.Name, out instanceSettings);
            var instanceInfo = new InstanceInfo
            {
                AppInstanceId                = appInstanceId,
                AppTypeId                    = appType.Id,
                InstanceName                 = instance.Name,
                Provider                     = instance.DatabaseProviderId,
                DataConnectionString         = GetConnectionString(dataConnectionStringTemplate, instance.MainDatabaseName),
                LobConnectionString          = GetConnectionString(lobConnectionStringTemplate, instance.LobDatabaseName),
                MigrateDatabase              = instance.MigrateDatabase,
                GeneratedCodeNamespace       = instance.GeneratedCodeNamespace,
                DbContextName                = instance.DbContextName,
                InstanceSettings             = instanceSettings,
                LoadBusinessFromAssemblyName = instanceSettings?.LoadBusinessFromAssemblyName,
                SortOrder                    = instance.SortOrder,
            };

            var bridge = new BusinessAssemblyBridge(
                instanceInfo, globalConfig,
                scope.ServiceProvider.GetRequiredService <ILogger <BusinessAssemblyBridge> >());
            var reflector = new BusinessReflector(metadataCache);

            var implementationsContainer = new ImplementationContainer
            {
                Metadata               = metadataCache,
                MetadataModel          = metadataModel,
                BusinessAssemblyBridge = bridge,
                Reflector              = reflector,
                InstanceInfo           = instanceInfo
            };

            switch (instanceInfo.Provider)
            {
            case DatabaseProviderEnum.MySql:
                var mySqlDbContextOptionsBuilder = new DbContextOptionsBuilder <LobToolsDbContext_MySql>();
                implementationsContainer._lobToolsDbContextOptions = mySqlDbContextOptionsBuilder
                                                                     .UseMySql(instanceInfo.LobConnectionString, ServerVersion.AutoDetect(instanceInfo.LobConnectionString)).Options;
                break;

            case DatabaseProviderEnum.SqlServer:
                var lobToolsDbContextOptionsBuilder = new DbContextOptionsBuilder <LobToolsDbContext>();
                implementationsContainer._lobToolsDbContextOptions = lobToolsDbContextOptionsBuilder.UseSqlServer(instanceInfo.LobConnectionString).Options;
                break;

            case DatabaseProviderEnum.PostgreSql:
                var postgreSqlDbContextOptionsBuilder = new DbContextOptionsBuilder <LobToolsDbContext_PostgreSql>();
                implementationsContainer._lobToolsDbContextOptions = postgreSqlDbContextOptionsBuilder.UseNpgsql(instanceInfo.LobConnectionString).Options;
                break;

            default:
                throw new NotImplementedException($"The provider {instanceInfo.Provider} is not implemented");
            }
            if (bridge.BusinessDbContextFactory == null)
            {
                scope.ServiceProvider.GetRequiredService <ILogger <ImplementationContainer> >().LogError($"Business assembly not loaded");
            }
            else
            {
                var dbContextType = bridge.BusinessDbContextFactory.GetType().Assembly.GetTypes().Single(x => x.IsPublic && x.IsSubclassOf(typeof(DbContext)));
                reflector.RegisterAssembly(dbContextType.Assembly);
                var dbContextOptionsBuilder = Activator.CreateInstance(typeof(DbContextOptionsBuilder <>).MakeGenericType(dbContextType)) as DbContextOptionsBuilder;
                switch (instanceInfo.Provider)
                {
                case DatabaseProviderEnum.MySql:
                    implementationsContainer._dbContextOptions = dbContextOptionsBuilder
                                                                 .UseMySql(instanceInfo.DataConnectionString, ServerVersion.AutoDetect(instanceInfo.DataConnectionString)).Options;
                    break;

                case DatabaseProviderEnum.SqlServer:
                    implementationsContainer._dbContextOptions = dbContextOptionsBuilder.UseSqlServer(instanceInfo.DataConnectionString).Options;
                    break;

                case DatabaseProviderEnum.PostgreSql:
                    implementationsContainer._dbContextOptions = dbContextOptionsBuilder.UseNpgsql(instanceInfo.DataConnectionString).Options;
                    break;

                default:
                    throw new NotImplementedException($"The provider {instanceInfo.Provider} is not implemented");
                }
            }
            return(implementationsContainer);
        }
Пример #5
0
        public static async Task <ImplementationContainer> Create(IServiceScope scope, MetadataDbContext dbContext, int appInstanceId)
        {
            var instance = await dbContext.AppInstances.FirstOrDefaultAsync(x => x.Id == appInstanceId);

            if (instance == null)
            {
                return(null);
            }
            if (!instance.IsEnabled)
            {
                return(null);
            }
            var appType = await dbContext.AppTypes.FirstOrDefaultAsync(x => x.Id == instance.AppTypeId);

            var bundle = await MetadataBundle.FromDbWithoutNavigations(dbContext, instance.AppTypeId, instance.Id);

            bundle.FixupRelationships();
            var metadataCache = new MetadataCache(bundle);
            var metadataModel = new MetadataModel(bundle);
            var instanceInfo  = new InstanceInfo
            {
                AppInstanceId    = appInstanceId,
                AppTypeId        = appType.Id,
                InstanceName     = instance.Name,
                Provider         = instance.DatabaseProviderId,
                ConnectionString = instance.DataConnectionString,
                MigrateDatabase  = instance.MigrateDatabase
            };

            var bridge = new BusinessAssemblyBridge(
                instanceInfo,
                scope.ServiceProvider.GetRequiredService <IOptions <GlobalConfiguration> >().Value,
                scope.ServiceProvider.GetRequiredService <ILogger <BusinessAssemblyBridge> >());
            var reflector = new BusinessReflector(metadataCache);

            var implementationsContainer = new ImplementationContainer
            {
                Metadata               = metadataCache,
                MetadataModel          = metadataModel,
                BusinessAssemblyBridge = bridge,
                Reflector              = reflector,
                InstanceInfo           = instanceInfo
            };

            if (bridge.BusinessDbContextFactory == null)
            {
                scope.ServiceProvider.GetRequiredService <ILogger <ImplementationContainer> >().LogError($"Business assembly not loaded");
            }
            else
            {
                var dbContextType = bridge.BusinessDbContextFactory.GetType().Assembly.GetTypes().Single(x => x.IsSubclassOf(typeof(DbContext)));
                reflector.RegisterAssembly(dbContextType.Assembly);
                var dbContextOptionsBuilder = Activator.CreateInstance(typeof(DbContextOptionsBuilder <>).MakeGenericType(dbContextType)) as DbContextOptionsBuilder;
                switch (instanceInfo.Provider)
                {
                case DatabaseProviderEnum.MySql:
                    implementationsContainer._dbContextOptions = dbContextOptionsBuilder.UseMySql(instanceInfo.ConnectionString).Options;
                    break;

                case DatabaseProviderEnum.SqlServer:
                    implementationsContainer._dbContextOptions = dbContextOptionsBuilder.UseSqlServer(instanceInfo.ConnectionString).Options;
                    break;

                default:
                    throw new NotImplementedException($"The provider {instanceInfo.Provider} is not implemented");
                }
            }
            return(implementationsContainer);
        }