Skip to content
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

Port Extend PossibleValuesAttribute with ServiceProvider to MORYX 8 #472

Merged
merged 7 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.1.0
8.2.0
6 changes: 3 additions & 3 deletions docs/articles/Core/Serialization/PossibleValues.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ public abstract class PossibleValuesAttribute : Attribute
public abstract bool UpdateFromPredecessor { get; }

/// <summary>
/// All possible values for this member represented as strings. The given container might be null
/// All possible values for this member represented as strings. The given containers might be null
/// and can be used to resolve possible values
/// </summary>
public abstract IEnumerable<string> GetValues(IContainer container);
public virtual IEnumerable<string> GetValues(IContainer container, IServiceProvider serviceProvider);

/// <summary>
/// String to value conversion. Must be override if <see cref="OverridesConversion"/> is set to true"/>
/// </summary>
public virtual object Parse(IContainer container, string value)
public virtual object Parse(IContainer container, IServiceProvider serviceProvider), string value)
{
return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<ItemGroup>
<ProjectReference Include="..\Moryx.AbstractionLayer\Moryx.AbstractionLayer.csproj" />
<ProjectReference Include="..\Moryx.Asp.Extensions\Moryx.Asp.Extensions.csproj" />
<ProjectReference Include="..\Moryx.Runtime\Moryx.Runtime.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Reflection;
using Moryx.Configuration;
using Moryx.Container;
using Moryx.Serialization;

namespace Moryx.AbstractionLayer.Products.Endpoints
Expand All @@ -31,7 +32,18 @@ static PartialSerialization()
/// <summary>
/// Creates a new <see cref="PartialSerialization{T}"/> instance
/// </summary>
public PartialSerialization() : base(null, new EmptyValueProvider())
[Obsolete("Use serialization with containers instead")]
public PartialSerialization() : this(null, null)
{
}

/// <summary>
/// Create serialization with access to global and local container
/// </summary>
/// <param name="localContainer"></param>
/// <param name="serviceProvider"></param>
public PartialSerialization(IContainer localContainer, IServiceProvider serviceProvider)
: base(localContainer, serviceProvider, new EmptyValueProvider())
{
}

Expand Down
37 changes: 25 additions & 12 deletions src/Moryx.AbstractionLayer.Products.Endpoints/ProductConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0

using Moryx.AbstractionLayer.Recipes;
using Moryx.Container;
using Moryx.Serialization;
using Moryx.Tools;
using Moryx.Workplans;
Expand All @@ -20,12 +21,19 @@ public class ProductConverter
// Null object pattern for identity
private static readonly ProductIdentity EmptyIdentity = new ProductIdentity(string.Empty, 0);

private static readonly ICustomSerialization ProductSerialization = new PartialSerialization<ProductType>();
private static readonly ICustomSerialization RecipeSerialization = new PartialSerialization<ProductionRecipe>();
private readonly ICustomSerialization _productSerialization;
private readonly ICustomSerialization _recipeSerialization;

public ProductConverter(IProductManagement productManagement)
public IContainer ProductManagerContainer { get; }
public IServiceProvider GlobalContainer { get; }

public ProductConverter(IProductManagement productManagement, IContainer localContainer, IServiceProvider globalContainer)
{
_productManagement = productManagement;
ProductManagerContainer = localContainer;
GlobalContainer = globalContainer;
_productSerialization = new PartialSerialization<ProductType>(localContainer, globalContainer);
_recipeSerialization = new PartialSerialization<ProductionRecipe>(localContainer, globalContainer);
}

public ProductDefinitionModel ConvertProductType(Type productType)
Expand All @@ -39,7 +47,7 @@ public ProductDefinitionModel ConvertProductType(Type productType)
Name = productType.FullName,
DisplayName = productType.GetDisplayName() ?? productType.Name,
BaseDefinition = baseTypeName,
Properties = EntryConvert.EncodeClass(productType, ProductSerialization)
Properties = EntryConvert.EncodeClass(productType, _productSerialization)
};
}

Expand Down Expand Up @@ -73,7 +81,7 @@ public ProductModel ConvertProduct(IProductType productType, bool flat)
// Properties
var typeWrapper = _productManagement.GetTypeWrapper(productType.GetType().FullName);
var properties = typeWrapper != null ? typeWrapper.Properties.ToArray() : productType.GetType().GetProperties();
converted.Properties = EntryConvert.EncodeObject(productType, ProductSerialization);
converted.Properties = EntryConvert.EncodeObject(productType, _productSerialization);

// Files
converted.Files = ConvertFiles(productType, properties);
Expand Down Expand Up @@ -124,7 +132,7 @@ private void ConvertParts(IProductType productType, IEnumerable<PropertyInfo> pr
DisplayName = displayName,
Type = FetchProductType(property.PropertyType),
Parts = partModel is null ? new PartModel[0] : new[] { partModel },
PropertyTemplates = EntryConvert.EncodeClass(property.PropertyType, ProductSerialization)
PropertyTemplates = EntryConvert.EncodeClass(property.PropertyType, _productSerialization)
};
connectors.Add(connector);
}
Expand All @@ -139,7 +147,7 @@ private void ConvertParts(IProductType productType, IEnumerable<PropertyInfo> pr
DisplayName = displayName,
Type = FetchProductType(linkType),
Parts = links?.Select(ConvertPart).ToArray(),
PropertyTemplates = EntryConvert.EncodeClass(linkType, ProductSerialization)
PropertyTemplates = EntryConvert.EncodeClass(linkType, _productSerialization)
};
connectors.Add(connector);
}
Expand All @@ -165,7 +173,7 @@ private PartModel ConvertPart(IProductPartLink link)
{
Id = link.Id,
Product = ConvertProduct(link.Product, true),
Properties = EntryConvert.EncodeObject(link, ProductSerialization)
Properties = EntryConvert.EncodeObject(link, _productSerialization)
};
return part;
}
Expand Down Expand Up @@ -214,7 +222,7 @@ public IProductType ConvertProductBack(ProductModel source, ProductType converte
// Copy extended properties
var typeWrapper = _productManagement.GetTypeWrapper(converted.GetType().FullName);
var properties = typeWrapper != null ? typeWrapper.Properties.ToArray() : converted.GetType().GetProperties();
EntryConvert.UpdateInstance(converted, source.Properties, ProductSerialization);
EntryConvert.UpdateInstance(converted, source.Properties, _productSerialization);

// Copy Files
ConvertFilesBack(converted, source, properties);
Expand Down Expand Up @@ -318,7 +326,12 @@ private static void ConvertFilesBack(object converted, ProductModel product, Pro
}
}

public static RecipeModel ConvertRecipe(IRecipe recipe)
[Obsolete("Use ConvertRecipe on instance")]
public static RecipeModel ConvertRecipe(IRecipe recipe) => ConvertRecipe(recipe, new PartialSerialization<ProductionRecipe>(null, null));

public RecipeModel ConvertRecipeV2(IRecipe recipe) => ConvertRecipe(recipe, _recipeSerialization);

private static RecipeModel ConvertRecipe(IRecipe recipe, ICustomSerialization serialization)
{
// Transform to DTO and transmit
var converted = new RecipeModel
Expand All @@ -328,7 +341,7 @@ public static RecipeModel ConvertRecipe(IRecipe recipe)
Type = recipe.GetType().Name,
State = recipe.State,
Revision = recipe.Revision,
Properties = EntryConvert.EncodeObject(recipe, RecipeSerialization),
Properties = EntryConvert.EncodeObject(recipe, serialization),
IsClone = recipe.Classification.HasFlag(RecipeClassification.Clone)
};

Expand Down Expand Up @@ -377,7 +390,7 @@ public IProductRecipe ConvertRecipeBack(RecipeModel recipe, IProductRecipe produ
productRecipe.Product = productType;
}

EntryConvert.UpdateInstance(productRecipe, recipe.Properties, RecipeSerialization);
EntryConvert.UpdateInstance(productRecipe, recipe.Properties, _recipeSerialization);

// Do not update a clones classification
if (productRecipe.Classification.HasFlag(RecipeClassification.Clone))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
using Moryx.Configuration;
using Moryx.Asp.Extensions;
using Moryx.AbstractionLayer.Properties;
using Microsoft.Extensions.DependencyInjection;
using Moryx.AbstractionLayer.Resources;
using Moryx.Runtime.Modules;
using System.ComponentModel;

namespace Moryx.AbstractionLayer.Products.Endpoints
{
Expand All @@ -27,10 +31,14 @@ public class ProductManagementController : ControllerBase
{
private readonly IProductManagement _productManagement;
private readonly ProductConverter _productConverter;
public ProductManagementController(IProductManagement productManagement)
public ProductManagementController(IProductManagement productManagement,
IModuleManager moduleManager,
IServiceProvider serviceProvider)
{
_productManagement = productManagement;
_productConverter = new ProductConverter(_productManagement);

var module = moduleManager.AllModules.FirstOrDefault(module => module is IFacadeContainer<IProductManagement>);
_productConverter = new ProductConverter(_productManagement, module.Container, serviceProvider);
}

#region importers
Expand All @@ -39,14 +47,16 @@ public ProductManagementController(IProductManagement productManagement)
[Authorize(Policy = ProductPermissions.CanViewTypes)]
public ActionResult<ProductCustomization> GetProductCustomization()
{
var parameterSerialization = new PossibleValuesSerialization(_productConverter.ProductManagerContainer, _productConverter.GlobalContainer,
new ValueProviderExecutor(new ValueProviderExecutorSettings().AddDefaultValueProvider()));
return new ProductCustomization
{
ProductTypes = GetProductTypes(),
RecipeTypes = GetRecipeTypes(),
Importers = _productManagement.Importers.Select(i => new ProductImporter
{
Name = i.Key,
Parameters = EntryConvert.EncodeObject(i.Value, new PossibleValuesSerialization(null, new ValueProviderExecutor(new ValueProviderExecutorSettings().AddDefaultValueProvider())))
Parameters = EntryConvert.EncodeObject(i.Value, parameterSerialization)
}).ToArray()
};
}
Expand Down Expand Up @@ -247,7 +257,7 @@ public ActionResult<RecipeModel[]> GetRecipes(long id, int classification)
var recipes = _productManagement.GetRecipes(productType, (RecipeClassification)classification);
var recipeModels = new List<RecipeModel>();
foreach (var recipe in recipes)
recipeModels.Add(ProductConverter.ConvertRecipe(recipe));
recipeModels.Add(_productConverter.ConvertRecipeV2(recipe));
return recipeModels.ToArray();
}
#endregion
Expand Down Expand Up @@ -330,7 +340,7 @@ public ActionResult<RecipeModel> GetRecipe(long id)
var recipe = _productManagement.LoadRecipe(id);
if (recipe == null)
return NotFound(new MoryxExceptionResponse {Title= string.Format(Strings.RecipeNotFoundException_Message, id) });
return ProductConverter.ConvertRecipe(recipe);
return _productConverter.ConvertRecipeV2(recipe);
}

[HttpPost]
Expand Down Expand Up @@ -380,7 +390,7 @@ public ActionResult<RecipeModel> CreateRecipe(string recipeType)
var recipe = _productManagement.CreateRecipe(recipeType);
if (recipe == null)
recipe = (IProductRecipe)TypeTool.CreateInstance<IProductRecipe>(recipeType);
return ProductConverter.ConvertRecipe(recipe);
return _productConverter.ConvertRecipeV2(recipe);
}
#endregion
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ public class ResourceModificationController : ControllerBase
private readonly IResourceTypeTree _resourceTypeTree;
private readonly ResourceSerialization _serialization;

public ResourceModificationController(IResourceManagement resourceManagement, IResourceTypeTree resourceTypeTree, IModuleManager moduleManager)
public ResourceModificationController(IResourceManagement resourceManagement,
IResourceTypeTree resourceTypeTree,
IModuleManager moduleManager,
IServiceProvider serviceProvider)
{
_resourceManagement = resourceManagement ?? throw new ArgumentNullException(nameof(resourceManagement));
_resourceTypeTree = resourceTypeTree ?? throw new ArgumentNullException(nameof(resourceTypeTree));
var module = moduleManager.AllModules.FirstOrDefault(module => module is IFacadeContainer<IResourceManagement>);
_serialization = new ResourceSerialization(module.Container);
_serialization = new ResourceSerialization(module.Container, serviceProvider);
}

[HttpGet]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal class ResourceSerialization : PossibleValuesSerialization
/// </summary>
private EntrySerializeSerialization _memberFilter = new();

public ResourceSerialization(IContainer container) : base(container, new ValueProviderExecutor(new ValueProviderExecutorSettings()))
public ResourceSerialization(IContainer container, IServiceProvider serviceProvider) : base(container, serviceProvider, new ValueProviderExecutor(new ValueProviderExecutorSettings()))
{
}

Expand Down
1 change: 1 addition & 0 deletions src/Moryx.Products.Samples/Moryx.Products.Samples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\Moryx.AbstractionLayer\Moryx.AbstractionLayer.csproj" />
<ProjectReference Include="..\Moryx.Products.Management\Moryx.Products.Management.csproj" />
<ProjectReference Include="..\Moryx.TestModule\Moryx.TestModule.csproj" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions src/Moryx.Products.Samples/Recipe/FacacadeRecipeValueAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using Moryx.Container;
using Moryx.Serialization;
using Moryx.TestModule;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Moryx.Products.Samples.Recipe
{
public class FacacadeRecipeValueAttribute : PossibleValuesAttribute
{
public override bool OverridesConversion => false;

public override bool UpdateFromPredecessor => false;

public override IEnumerable<string> GetValues(IContainer localContainer, IServiceProvider serviceProvider)
{
var module = serviceProvider.GetRequiredService<ITestModule>();
return new[] { module.Bla.ToString("D") };
}
}
}
2 changes: 1 addition & 1 deletion src/Moryx.Products.Samples/Recipe/WatchProductRecipe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public WatchProductRecipe(WatchProductRecipe source) : base(source)
Case = source.Case;
}

[EntrySerialize]
[EntrySerialize, FacacadeRecipeValue]
[DisplayName("Cores Installed")]
public int CoresInstalled { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ public class ModulesController : ControllerBase
private readonly IModuleManager _moduleManager;
private readonly IConfigManager _configManager;
private readonly IParallelOperations _parallelOperations;
private readonly IServiceProvider _serviceProvider;

public ModulesController(IModuleManager moduleManager, IConfigManager configManager, IParallelOperations parallelOperations)
public ModulesController(IModuleManager moduleManager, IConfigManager configManager, IParallelOperations parallelOperations, IServiceProvider serviceProvider)
{
_moduleManager = moduleManager;
_configManager = configManager;
_parallelOperations = parallelOperations;
_serviceProvider = serviceProvider;
}

[HttpGet("dependencies")]
Expand Down Expand Up @@ -264,7 +266,7 @@ public ActionResult<Entry> InvokeMethod([FromRoute] string moduleName, [FromBody
/// </summary>
private ICustomSerialization CreateSerialization(IServerModule module)
{
return new PossibleValuesSerialization(module.Container, (IEmptyPropertyProvider)_configManager)
return new PossibleValuesSerialization(module.Container, _serviceProvider, (IEmptyPropertyProvider)_configManager)
{
FormatProvider = Thread.CurrentThread.CurrentUICulture
};
Expand Down
Loading
Loading