Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Make workplans immutable and increment versions automatically #87

Merged
merged 1 commit into from
Mar 24, 2021
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
75 changes: 72 additions & 3 deletions src/Moryx.Products.Management/Implementation/RecipeManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@

using System;
using System.Collections.Generic;
using System.Linq;
using Moryx.AbstractionLayer.Products;
using Moryx.AbstractionLayer.Recipes;
using Moryx.Container;
using Moryx.Model;
using Moryx.Model.Repositories;
using Moryx.Products.Model;
using Moryx.Workflows;

namespace Moryx.Products.Management
{
[Component(LifeCycle.Singleton, typeof(IRecipeManagement))]
internal class RecipeManagement : IRecipeManagement
[Component(LifeCycle.Singleton, typeof(IRecipeManagement), typeof(IWorkplans))]
internal class RecipeManagement : IRecipeManagement, IWorkplans
{
#region Dependencies

public IProductStorage Storage { get; set; }

public IUnitOfWorkFactory<ProductsContext> UowFactory { get; set; }
public IUnitOfWorkFactory<ProductsContext> ModelFactory { get; set; }

#endregion

Expand Down Expand Up @@ -55,6 +58,72 @@ public void Save(long productId, ICollection<IProductRecipe> recipes)
RaiseRecipeChanged(recipe);
}

public IReadOnlyList<Workplan> LoadAllWorkplans()
{
using (var uow = ModelFactory.Create())
{
var repo = uow.GetRepository<IWorkplanEntityRepository>();
var workplans = (from entity in repo.Linq.Active()
select new Workplan
{
Id = entity.Id,
Name = entity.Name,
Version = entity.Version,
State = (WorkplanState)entity.State
}).ToArray();
return workplans;
}
}

public Workplan LoadWorkplan(long workplanId)
{
using (var uow = ModelFactory.Create())
{
return RecipeStorage.LoadWorkplan(uow, workplanId);
}
}

public long SaveWorkplan(Workplan workplan)
{
using (var uow = ModelFactory.Create())
{
var recipeRepo = uow.GetRepository<IProductRecipeEntityRepository>();
// Update all non-clone recipes of that workplan
var affectedRecipes = recipeRepo.Linq
.Where(r => r.WorkplanId == workplan.Id && r.Classification > 0).ToList();

var entity = RecipeStorage.SaveWorkplan(uow, workplan);
foreach (var recipe in affectedRecipes)
{
recipe.Workplan = entity;
}

uow.SaveChanges();

foreach (var recipeEntity in affectedRecipes)
{
var recipe = Storage.LoadRecipe(recipeEntity.Id);
RaiseRecipeChanged(recipe);
}

return entity.Id;
}
}

public void DeleteWorkplan(long workplanId)
{
using (var uow = ModelFactory.Create())
{
var repo = uow.GetRepository<IWorkplanEntityRepository>();
var workplan = repo.GetByKey(workplanId);
if (workplan == null)
return; // TODO: Any feedback?
repo.Remove(workplan);
uow.SaveChanges();

}
}

private void RaiseRecipeChanged(IRecipe recipe)
{
// This must never be null
Expand Down
12 changes: 8 additions & 4 deletions src/Moryx.Products.Management/Implementation/RecipeStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,19 @@ public static WorkplanEntity SaveWorkplan(IUnitOfWork uow, Workplan workplan)
// If it is a new plan we need a new object
if (workplanEntity == null)
{
workplanEntity = workplanRepo.Create(workplan.Name, workplan.Version, (int)workplan.State);
workplanEntity = workplanRepo.Create(workplan.Name, 1, (int)workplan.State);
EntityIdListener.Listen(workplanEntity, workplan);
}
// If it was modified or the version increased we create a new one and reference the old one
else if (workplan.Version > workplanEntity.Version)
// If it was modified we write to a new entity and increment the version
else
{
// Flag the previous version deleted, to hide it from the list but keep it accessible by old recipes
workplanRepo.Remove(workplanEntity);

// Create a reference link between old and new version
var reference = referenceRepo.Create((int)WorkplanReferenceType.NewVersion);
reference.Source = workplanEntity;
reference.Target = workplanEntity = workplanRepo.Create(workplan.Name, workplan.Version, (int)workplan.State);
reference.Target = workplanEntity = workplanRepo.Create(workplan.Name, workplanEntity.Version + 1, (int)workplan.State);
EntityIdListener.Listen(workplanEntity, workplan);
}

Expand Down
74 changes: 0 additions & 74 deletions src/Moryx.Products.Management/Implementation/WorkplanManagement.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,27 @@ public void FullCycle()
var workplan = CreateWorkplan();

// Act
Workplan loaded;
WorkplanEntity entity;
Workplan loaded, loaded2;
WorkplanEntity entity1, entity2;
using (var uow = _factory.Create())
{
entity = RecipeStorage.SaveWorkplan(uow, workplan);
entity1 = RecipeStorage.SaveWorkplan(uow, workplan);
uow.SaveChanges();
loaded = RecipeStorage.LoadWorkplan(uow, entity.Id);
loaded = RecipeStorage.LoadWorkplan(uow, entity1.Id);

loaded.Name = "Modified";

entity2 = RecipeStorage.SaveWorkplan(uow, loaded);
uow.SaveChanges();
loaded2 = RecipeStorage.LoadWorkplan(uow, entity2.Id);
}

// Assert
Assert.AreEqual(workplan.Id, entity.Id, "Id not assigned to original object!");
Assert.AreEqual(workplan.Name, loaded.Name, "Name not correctly stored and saved");
Assert.AreNotEqual(entity1.Id, entity2.Id);
Assert.AreEqual(workplan.Id, entity1.Id, "Id not assigned to original object!");
Assert.AreEqual(workplan.Name, entity1.Name, "Name not correctly stored and saved");
Assert.AreEqual(loaded.Name, entity2.Name, "Name not correctly stored and saved");
Assert.AreEqual(loaded.Name, loaded2.Name, "Name not correctly stored and saved");
Assert.AreEqual(workplan.State, loaded.State);
Assert.AreEqual(workplan.MaxElementId, loaded.MaxElementId);

Expand Down