Prob: objects props not known at designtime

Prob: objects props not known at designtime

Old forum URL: forums.lhotka.net/forums/t/9596.aspx


vschaak posted on Sunday, October 03, 2010

Hi @ll,

beeing a CSLA-newbie, I'll got to face a new challenge:

Our team is going to create a successor of an older, data driven app. With this, different customers are able to customize (add new ones!) properties (and their corresponding controls!) of certain objects (in fact the old app isn't OO, but data driven) around some core properties, that are allways present. Since this feature is unique and well needed in this part of the market, our new app should have a similar feature...
My first attempt was to add a "list of extented pros" as a property to the core object, but how to make sure CSLA treat those props just like the core props? And how to make the forms (ie. Winforms and ASP/maybe SL later as well) host binded controls to props that have to be generated at runtime?

...

Any push into "the right" direction?

Thanks 'n good luck

Volker

tiago replied on Sunday, October 03, 2010

Hi Volker,

Dynamic properties or custom properties is a standing issue. I've read a lot about it in CSLA forum, Code Project site or elsewhere.

1. Requisites: What is exactly the problem?

A property is just data. From that point of view, we need to know the property name, data type and the data value. This looks simple enough.

Now let's build a bit upon this foundation.

1.1. Class level definiton or sub-type definition

These custom properties will be the same for every instance of a class? Given a TV program class, for a "sports" TV program type you will need some custom properties and for a "movie" TV program type you will nedd different custom properties. If you have this requisite, things can get complicated, not because it's harder to store or get that data, but because of other operations you might need to do with that data.

1.1 Searching

Will you need to seach that data? Do you need to include those properties in a CSLA Criteria? Now suppose each TV program type can have a different set of custom properties. How would you design the search form? How will you solve the criteria issue?

1.2. Listing

You will be asked to show the custom properties on the object form. No big deal. Suppose you will also be asked to show those fields in a DataGrid or on a report. Now take the scenario of having different sets of custom properties per TV program type. Will you force each type into its own DataGrid or report? Or will you just show the common parts?

1.3. Authorization and Validation

Your custom properties need specific authorization rules or will they share the autorization rules of the object? Say, if this user/role has read/write access to the object, he has also read/write access to the custom properties of the same object.

And what about business/validation rules? Will you use some regex magic? Do you need to have dependent properties? Say you have a "city" combobox that is dependent upon the "state" combobox selection. No regex in the world can help.

What I'm discussing here is the need (or no need) of code injection in order to fully support CSLA features.

2. The easy solution

If all you  need is the data - no criteria, no listings, no authorization, regex validation or no validation - you can get away with a collection of ICustomProperty objects.

First define a ICustomProperty

using Csla.Core;

namespace DocStoreBO.CustomProperties
{
    public interface ICustomProperty : IEditableBusinessObject
    {
        string Type { getset; }
        string Name { getset; }
        string Value { getset; }
    }
}

now CustomPropertyBase just for ease of use

using System;
using Csla.Core;

namespace DocStoreBO.CustomProperties
{
    [Serializable]
    public abstract class CustomPropertyBase : BusinessBaseICustomProperty
    {
        public virtual string Type { getset; }

        public virtual string Name
        {
            get { return ToString(); }
            set { return; }
        }

        public virtual string Value { getset; }
    }
}

StringProperty is a concrete implementation for strings property type

namespace DocStoreBO.CustomProperties.CustomPropertyTypes
{
    public class StringProperty : CustomPropertyBase
    {
        public override string Type
        {
            get { return "String"; }
            set { return; }
        }
    }
}

and finally the class you will add to your object a CustomPropertyCollection

using System;
using Csla;

namespace DocStoreBO.CustomProperties
{
    [Serializable]
    public class CustomPropertyCollection : BusinessBindingListBase<CustomPropertyCollectionICustomProperty>
    {
    }
}

Add it like this

private static PropertyInfo<CustomPropertyCollectionCustomFieldsProperty = RegisterProperty<CustomPropertyCollection>(p => p.CustomFields"CustomFields"RelationshipTypes.Child);
public CustomPropertyCollection CustomFields
{
    get { return GetProperty(CustomFieldsProperty); }
}

In this collection you can have as many custom/dynamic properties as you need.

3. The hard solution

I confess this isn't enough for my requisites. I need Criteria, and full CSLA Authorization and business/validation rules. You might think that there aren't a lot of choices. Surprisingly there are different choices! You must use reflection for each and every solution for this requisites. After all we must put there (read inject) code that doesn't exist at compile time. Code injection can be more or less eficient and Reflection.Emit isn't the fastest way to do things. I found 3 solutions:

I'm far from having a prototype and this is not at the top of my priority list. Anyway the best I found is at http://www.codeproject.com/KB/cs/DynamicClass.aspx. This guy explores the in memory assembly path. It takes longer when the program starts, but you get full speed code. As you don't save the assembly, you don't have to solve problems about file access, local vs. remote access. Note this example is running in Silverlight 4.

RockfordLhotka replied on Monday, October 04, 2010

You might also look at some of the new .NET 4 dynamic features. The Dynamic Language Runtime (DLR) provides some interesting capabilities around creating types at runtime without resorting to Reflection.Emit. I believe ASP.NET MVC 3 is making use of some of these features now to build dynamic types at runtime.

vschaak replied on Tuesday, October 05, 2010

Hi Tiago,

thank you for your in depth answer.

The prob I encounter isn't that of subclassing ("TV-movie and TV-sports are both of type TV-programm, share some props but have props the other one doesnt"), but of classes that have the same props at every instance, at least at the app-instance of a certain customer. Another customer should be able to add his own props.

Your 'easy solution' is exactly what I thought about at first. Unfortunatly I assume, that this a shot to short for our requirements Sad I think I've got to make some experiments to get closer to the probs and a possible solution. (Sorting, Filtering and listing, together with other UI-stuff definitly should be in the functionalities of our app)

So, thanks again and good luck with your hunt for a solution...

Best wishes

Volker

Copyright (c) Marimer LLC