private List <ProviderProperty> GetProperties(Type type) { List <ProviderProperty> result = new List <ProviderProperty>(); var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var property in properties) { try { ProviderProperty providerProperty = new ProviderProperty(); providerProperty.Name = property.Name; providerProperty.TypeName = property.Name; providerProperty.Type = GetTypeFromProperty(property, out Type genericParameter); if (genericParameter != null) { providerProperty.Attributes.Add(new ProviderPropertyAttribute(PropertyAttribute.GenericParameter, genericParameter.AssemblyQualifiedName)); } var attributes = property.GetCustomAttributes(true); foreach (var attribute in attributes) { switch (attribute) { case DisplayAttribute da: providerProperty.Name = da.Name; providerProperty.Description = da.Description; break; case PasswordPropertyTextAttribute ppta: providerProperty.Attributes.Add(new ProviderPropertyAttribute(PropertyAttribute.Password, bool.TrueString)); break; case TransformAttribute ta: providerProperty.Attributes.Add(new ProviderPropertyAttribute(PropertyAttribute.Transform, bool.TrueString)); break; } } result.Add(providerProperty); } catch { } } return(result); }
set => SetValue(ProviderProperty, value);
private async Task ProcessProvider(Type type, Type genericType, ProviderType providerType) { Provider provider = new Provider(); DisplayNameAttribute displayAttribute = type.GetCustomAttribute <DisplayNameAttribute>(); if (displayAttribute != null) { provider.Name = displayAttribute.DisplayName; } else { provider.Name = type.Name; } provider.FullName = type.FullName; provider.Namespace = type.AssemblyQualifiedName; provider.Type = providerType; provider.Version = type.Assembly.GetName().Version.ToString(); provider.GenericType = genericType?.AssemblyQualifiedName; provider.Properties = GetProperties(type); var existingProvider = dbContext.Providers.Include(p => p.Properties).FirstOrDefault(p => p.FullName.Equals(provider.FullName)); if (existingProvider != null) { bool modelHasChanged = false; // check if the metadata of the provider has changed if (!existingProvider.Equals(provider, false)) { if (existingProvider.Type != provider.Type) { modelHasChanged = true; } existingProvider.Name = provider.Name; existingProvider.FullName = provider.FullName; existingProvider.Namespace = provider.Namespace; existingProvider.Version = provider.Version; existingProvider.Type = provider.Type; } // check if the properties of the provider has changed // remove non longer existing properties for (int i = existingProvider.Properties.Count - 1; i >= 0; i--) { ProviderProperty providerProperty = provider.Properties.FirstOrDefault(p => p.TypeName == existingProvider.Properties[i].TypeName); if (providerProperty == null) { existingProvider.Properties.RemoveAt(i); modelHasChanged = true; } } // add or update properties foreach (var property in provider.Properties) { ProviderProperty existingProperty = existingProvider.Properties.FirstOrDefault(p => p.TypeName == property.TypeName); if (existingProperty == null) { existingProvider.Properties.Add(property); modelHasChanged = true; } else if (!existingProperty.Equals(property, false)) { existingProperty.Name = property.Name; existingProperty.TypeName = property.TypeName; existingProperty.Type = property.Type; existingProperty.Description = property.Description; existingProperty.Attributes.Clear(); existingProperty.Attributes = property.Attributes; modelHasChanged = true; } } if (modelHasChanged) { // find all jobs that uses the changed model var jobsWithChangedModels = dbContext .Jobs .Include(j => j.Providers) .Where(j => j.Providers.Any(t => t.ID == existingProvider.ID)); // TODO: handle authenticated sessions // set the jobs to have a changed model foreach (BackupJob job in jobsWithChangedModels) { job.HasChangedModel = true; } } } else { await dbContext.Providers.AddAsync(provider); } try { await dbContext.SaveChangesAsync(); } catch { // TODO: log } }