We are building a system that will require a high level of runtime customization. The core functionality of the system is a generic grid and record editor. There are several system defined types (e.g. Contact and Message).

End users should be able to create several lists of Contacts and of Messages. Each list may have different custom fields. All these definitions are thought to be persisted in a separate configuration database so that it can be loaded before the actual data domain is built.

I have done some testing and realized that it is very easy to add these custom fields to the Entities using DefineField in the OnDefinitionsBuilt method of a DO.NET Module. The problem is that we are using dynamic LINQ for our grid and querying, and when we pass in the name of the custom field, it fails since the .NET Property does not exist (DLINQ uses reflection to bind to the actual property defined in the class).

This led me to think that it might be easier to generate custom types at runtime (basically one type for each list) and do a compile before the domain is built, similar to how the ProxyAssembly in previous versions of DO worked. This would ensure that each type is a "proper entity class". We could use dynamic LINQ and do not have to distinguish between custom and system fields when handling querying, loading and saving.

Another handy thing is that we could pretty easily extend this system to support custom logic by overriding methods and put in custom code (though in most cases it would probably be better to solve this using an OO design pattern).

I didn't finish the runtime compile experiment since I didn't have time to look into executing PostSharp on the dynamically compiled assemblies. One main issue I thought of is then licensing of DO.NET and/or PostSharp. It would have to do this compilation on one or more servers. How would that work? Is there a runtime / redistributable license that handles compilation of custom assemblies?

The reason for writing this here, is that I would like to get some feedback and recommendations on what to do. Is there a way of making DLINQ work with fields that are not properties? As far as I can see, the entity.GetProperty() methods cannot be translated by the LINQ translators. If that had worked, we could use that instead of DLINQ, meaning that we do not really need to have the fields defined as .NET Properties.

A more simple (but limiting) way of doing this would be to just limit the number of custom fields we want to support and call them CustomString[1-10], CustomDate[1-10] etc. Then in the customization configuration we would need to map the configured fields to one of these custom fields.

I'd appreciate any feedback and tips on how to resolve this.

asked Feb 11 '11 at 05:54

tmyklebust's gravatar image

tmyklebust
48559


One Answer:

I didn't have time to look into executing PostSharp on the dynamically compiled assemblies

Most likely, you simply don't need it. Emitting the calls to necessary Persistent methods from generated properties is much easier option - see what kind of code we use there (e.g. with Reflector) and do the same. Also, see the code we use in constructors (they're also processed by PostSharp).

Since there will be no methods, you don't need to do anything with them. Inherited methods (the ones from your base types) are already processed.

One main issue I thought of is then licensing of DO.NET and/or PostSharp.

In case I just described you don't need any compile-time components in runtime, so there are no any issues with licensing.

If you'll really need a redistributable license for DO+PostSharp limited to the scope of your own products, please contact us. We're working on providing this option shortly.

Is there a way of making DLINQ work with fields that are not properties? As far as I can see, the entity.GetProperty() methods cannot be translated by the LINQ translators.

If I'm not mistaken, they should be translated - I remember we at least thought about this. The main requirement here is that argument of such call must be a constant string expression.

But I anyway recommend you to use runtime code generation instead of this option - simply because it is much safer and native from all the points. Otherwise you may discover LINQ was just the first issue later. Yes, it's a bit more complex way, but since difference is just in few dozens of LOC, the complexity is less important factor here.

A more simple (but limiting) way of doing this would be to just limit the number of custom fields we want to support and call them CustomString[1-10], CustomDate[1-10] etc.

This approach works if you don't need to index custom fields.

answered Feb 11 '11 at 10:24

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

edited Feb 11 '11 at 10:24

Thanks for your help. I ended up generating and compiling the entities at runtime.

(Feb 21 '11 at 10:55) tmyklebust tmyklebust's gravatar image

You're welcome :)

(Feb 21 '11 at 13:18) Alex Yakunin Alex%20Yakunin's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

Subscription:

Once you sign in you will be able to subscribe for any updates here

Tags:

×12
×2

Asked: Feb 11 '11 at 05:54

Seen: 9,701 times

Last updated: Feb 21 '11 at 13:18

powered by OSQA