2

We have a legacy ASP.Net application (written in c# a few years ago) which allows a factory manufacture a number of custom-made products. Different attributes such as color, length, width, etc. are common for all product types, but each product type carries a set of attributes specific to type. The application currently has a base product class, followed by a number of classes each for each type.

Also, every type has its own set of web forms specific to the type. selection between the types is given by a switch statement which directs the code execution based on product type to the relevant web form. In addition, a single with some 70 fields is used to hold all products manufactured, with only the fields relevant to product type populated.

We are now trying to refactor this application, so as to be able to add new products without having to change the code extensively. Also we would like to not have to build new web forms for each new type of product but rather have the forms created dynamically (we are moving to MVC now). We would like if possible to move from development to configuration. Is there a "canonic approach" for this kind of task?

  • "Does anyone have experience in such a project?" is not the sort of question we answer here. I assume what you're actually interested in is how to minimize the code changes involved in adding a new type. I would think this is done simply by having a hierarchy of Product classes and a related hierarchy of ProductWebForm classes, or by figuring out how to make your product attributes generic enough that only one class with some freeform data is required. Is there a specific problem you've encountered when trying to do this? In other words, what do you actually need help with? – Ixrec Dec 20 '15 at 20:52
  • thanks for your response; I apologise for notting posting the question properly; What I am looking for is a model which can easily be extended when new types are added with minimum code changes; to be more exact let's consider that we have a factory which makes chairs such as office chairs which include wheels and levers for adjusting height, swiveling mechanism type, aluminum tubes, etc; then we have dining chairs which are static and this don't require the above but which require wood type; now both office chair type and dining chair types require fabric code.Future models may require more. – cloucas Dec 21 '15 at 6:51
3

Yes, But you dont say what you are doing with the products.

If you just need to record the information, then you only need a single Product with a dictionary of attributes.

Then a single view can loop through the collection and produce forms for any product 'type'

If however you have custom logic to implement per type any generic system will soon become too complex. You end up inventing a new programming language for your configuration which is a nightmare to maintain.

Rather than go down that route I would suck up the short term pain of a view per model.

edit -----

code example for simple dictionary model

using System.Collections.Generic;
    public class Product
    {
        public Dictionary<string, string> Attributes { get;set }
    }
    public class ProductFactory
    {
        public Product Create(string productType)
        {
            Product p  = new Product();
            if(productType == "chair")
            {
                p.Attributes.Add("legCount","4");
                p.Attributes.Add("material","pine wood");
            }
            return p;
        }
    }

razor view snippet

@foreach(KeyValuePair kvp in Model.Attributes)
{
    <label>@kvp.Value<label> <input type="text" name="@kvp.Key" value="@kvp.Value"/>
}

Views on EAV answer :

In my view this is the next level up. You replace the strings with objects and add meta data to tell the form how to render for specific types. However, (briefly) in my view this only pushes the requirement for custom forms down to the attribute level and you are better off just going for custom forms per product

Problems with this simple dictionary approach :

You no longer have strongly typed products. At some point you need to convert the string "4" legs into an actual number of legs. if the user has typed "four" you will get a run time error.

To clarify :

If you want my recommendation, it's "don't do autogenerated forms"

  • thanks for your response; I apologise for notting posting the question properly; What I am looking for is a model which can easily be extended when new types are added with minimum code changes; to be more exact let's consider that we have a factory which makes chairs such as office chairs which include wheels and levers for adjusting height, swiveling mechanism type, aluminum tubes, etc; then we have dining chairs which are static and this don't require the above but which require wood type; now both office chair type and dining chair types require fabric code.Future models may require more – cloucas Dec 21 '15 at 6:54
  • the dictionary of attributes should work for that – Ewan Dec 21 '15 at 8:41
  • @Ewan: a dictionary is a good mental model to start from, but it will typically not be enough if different attribute types are needed, and you want to generate your Webforms from this. You will need extra meta information. – Doc Brown Dec 21 '15 at 9:48
  • @doc key requirement in my mind is "not have to build new web forms" your EVA approach with typed attributes will require custom partial views per type. as you say yourself, bit of an antipattern between the full custom types and the simplistic dictionary<string,string> approach – Ewan Dec 21 '15 at 16:24
  • @Ewan: the requirement of the OP was clear: he wants his products equipped with something like "user defined attributes", and his forms to be created dynamically. When a simple dictionary serves that purpose, fine (the only meta information there will be the attribute name as the keys in that dictionary, for some very simple cases that might be enough, for more complex it won't). If that leads to partial custom views or full custom views is completely independent from using an EAV approach or a simple dictionary. – Doc Brown Dec 21 '15 at 16:52
4

What you are looking for is called "Entity Attribute Value" model. It will allow you to have a metamodel in your database, which describes the list of attributes of each entity (in your case the Product types). The metamodel can be changed at run time, so you can add new product types without changing your application. And you can provide additional information there like "datatype", "allowed range of values", "is the attibute mandatory or optional", "minimum width" and so on which is necessary for generating a useful form for this data.

To implement this, you will need to add some functionality to your application to manage the list of available product types and the list of attributes of each type.

Beware, EAV is often seen as an anti-pattern, because it can add more additional complexity to a program than one typically expects. So my recommendation is to use it only for product attributes where you really need that kind of flexibility, the "user defined attributes", not for the attributes common for all product types. It is perfectly possible to implement EAV only partial, or in a downsized variant which suits your needs. For example, you can provide a certain list of standard products, for instance, a "basic chair", a "basic table", builtin into the application, and each attribute a classic row in your database table. Then you let the user create something like a dining chair or an office chair as extensions of the "basic chair", by giving him add the ability to the missing attributes by himself (and only those attributes will become part of the EAV model).

  • Only IFF you intend to do it using a RDBMS. EAV is an anti-pattern because it is a NoSQL database inside a SQL database. Perhaps it makes more sense to go NoSQL to begin with. – ArTs Dec 22 '15 at 5:28
  • 1
    @arts you can make a table per attribute type and specify all the cols if you want to keep it normalized – Ewan Dec 22 '15 at 7:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.