A ValueService is used to share data among objects I have C# code that makes some calculations for physical models. I have this project class:

public class Project
{
    public IEnumerable&lt;GenericComponent&gt; components;
    private ValueService valueService = new ValueService(Guid.NewGuid().ToString());

    public Project(string norm)
    {
        components = FactoryGenerator.GetFactory(norm).GetComponents();
    }

    public void SetValues(IEnumerable&lt;ValueViewModel&gt; values)
    {
        values.ToList().ForEach(t =&gt; valueService.SetValue(t.Key, t.Value));
    }

    public bool Valid(string componentName)
    {
        return components.Where(s =&gt; s.Title == componentName).Single().Valid();
    }
}


That creates smaller components that do some calculations. E.g. 

public class CrossSectionComponent: GenericComponent
{
    public CrossSectionComponent(ValueService valueService): base(valueService)
    {

    }

    ICrossSectionViewModel crossSection;

    double valuex; 

    override
    public bool Valid()
    {
        return valuex &gt; valueService.GetValue&lt;double&gt;("valuey") ? true : false;
    }
}


Each component has a list of values with keys that are unique over the entire model. At the moment I use a ValueService, where each component registers its values with the respective keys. The ValueService can be used to get values from other components in order to do validation calculations. 

    private string projectUUID;
    private List&lt;ValueViewModel&gt; values = new List&lt;ValueViewModel&gt;();

    public ValueService(string projectUUID)
    {
        this.projectUUID = projectUUID;
    }

    public void RegisterValue(string key)
    {
        if (!this.hasKey(key))
        {
            values.Add(new ValueViewModel()
            {
                Key = key,
            });
        }
    }

    public void SetValue(string key, object value)
    {
        if (this.hasKey(key))
            this.values.Find(t =&gt; t.Key == key).Value = value;
    }

    public T GetValue&lt;T&gt;(string key)
    {
        return (T)values.Find(t =&gt; t.Key == key)?.Value;
    }

    private bool hasKey(string key)
    {
        return values.Any(t =&gt; t.Key == key);
    }
}


This is part of a stateless API, i.e. for each HTTP request (at the moment) a new Project object is generated and used to make validations. 

My API controller looks like this:

    public IActionResult postData([FromRoute] string norm, [FromRoute] string component, [FromBody] ValueViewModel[] data)
    {
        Project project = new Project(norm);
        project.SetValues(data);
        return Ok(project.Valid(component));
    }


The validity of one component does depend in most cases on values of other components. If one wants to check the validity of a components, the use sends a list of values (ValueViewModel[] data), the server creates the project where all available values are stored. Then IF AND ONLY IF all required values are set, the validity can actually be calculated. If not all values are provided inside the "data list", then the validity of said component is false. So there are two cases where component.Valid() => false


The calculations yield false
Not all values have been submitted


My concerns are


When the project continues, the number of components will get quite large, I fear there will be a performance issue if for each request the whole set of components needs to be generated --> should I use LazyLoading?
Is the ValueService approach good to share data between the components? Is there a better solution?
You have built a system of components and shared objects, but don't use its potential. In fact, for your use case the complete setup is an overkill.


There is no component hierarchy
There are no component-sensitive or -specific values
You only need a single component to verify any incoming request



 public IActionResult postData(
        [FromRoute] string norm, 
        [FromRoute] string component, 
        [FromBody] ValueViewModel[] data)
    {
        Project project = new Project(norm);
        project.SetValues(data);
        return Ok(project.Valid(component));
    }



For the aforementioned reasons, I don't see a need for having a list of components and values. I would rewrite the API to be as simple as possible:


Let the factory retrieved by FactoryGenerator get the requested component
Let that component validate the input values


code:

public IActionResult postData(
        [FromRoute] string norm, 
        [FromRoute] string component, 
        [FromBody] ValueViewModel[] data)
    {
        var component = FactoryGenerator.GetFactory(norm).GetComponent(component);
        return Ok(component.Valid(data));
    }