template studio 2.5 template binding

Posts   
 
    
JieMa
User
Posts: 6
Joined: 09-Jun-2008
# Posted on: 10-Jun-2008 17:50:17   

In LLBLGen Pro 2.5, I tried to custom template to add optimistic locking. Purpose is to generate DAL by adding locking check.

I tried to look into

I have reviewed the post http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=2316&HighLight=1

It looks pretty old post. I can not find the config file mentioned in the post.

Is there any guideline I can look into?

Walaa avatar
Walaa
Support Team
Posts: 14987
Joined: 21-Aug-2005
# Posted on: 11-Jun-2008 11:15:42   

I have reviewed the post http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=2316&HighLight=1

It looks pretty old post. I can not find the config file mentioned in the post.

That's an old post, and things have changed since then.

I think what you are up to can be easily done using Dynamic Injection.

In LLBLGen Pro 2.5, I tried to custom template to add optimistic locking. Purpose is to generate DAL by adding locking check.

You can use LLBLGen's Concurrency Control mechanism. Please check Concurrency control in the LLBLGen Pro manual, under "Using the generated code -> Adapter/SelfServicing -> Using the entity classes"

All you need to do is to implement the IConcurrencyPredicateFactory, and then you can use DI to inject instances of this class to the ConcurrencyPredicateFactoryToUse property of the specified entities, without the need of include templates.

JieMa
User
Posts: 6
Joined: 09-Jun-2008
# Posted on: 11-Jun-2008 18:10:31   

I have read the section Concurrency control mechanism, I am trying to implement IconcurrencyPredicateFactory interface in the partial Entity Class, here is code I plan to add. Pls. check if this is the "OK" solution in this scenario. I need to get confirm if I need to any more modification in the code.

I tried to check concurrency when save userEntity

public partial class UserEntity : IConcurrencyPredicateFactory { public IPredicateExpression CreatePredicate( ConcurrencyPredicateType predicateTypeToCreate, object containingEntity) { UserEntity user = (UserEntity)containingEntity;

        EntityField2 timestampField =
            (EntityField2)EntityFieldFactory.Create(user.GetType().Name, "ConcurrencyTimeStamp");

        IPredicateExpression expression = new PredicateExpression();

        switch (predicateTypeToCreate)
        {
            case ConcurrencyPredicateType.Save:
                expression.Add(timestampField == user.Fields["ConcurrencyTimeStamp"].DbValue);
                break;
        }

        return expression;
    }
  }
daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 12-Jun-2008 04:09:33   

As you are expecting UserEntity objects, I only can recommend you this simplification.

public partial class UserEntity : IConcurrencyPredicateFactory
     {
        public IPredicateExpression CreatePredicate(
            ConcurrencyPredicateType predicateTypeToCreate,  object containingEntity)
        {
            UserEntity user = (UserEntity)containingEntity;
            IPredicateExpression expression = new PredicateExpression();

            switch (predicateTypeToCreate)
            {
                case ConcurrencyPredicateType.Save:
                    expression.Add(UserFields.ConcurrencyTimeStamp == user.Fields["ConcurrencyTimeStamp"].DbValue);
                    break;
            }

            return expression;
        }
     }

(Edit) Sorry. I read your posted forum link. And according to your scenario, your code is Ok as far as I can see simple_smile

David Elizondo | LLBLGen Support Team
JieMa
User
Posts: 6
Joined: 09-Jun-2008
# Posted on: 14-Jun-2008 00:11:23   

Well, we decided to go back DI solution. Here is the code I plan to use. Pls. let me know if I made any mistakesimple_smile . We do not want to this class depend on any LLBL Generated code is possible.

using System; using System.Reflection;

using CSRS.LLBLGenPro;

using SD.LLBLGen.Pro.ORMSupportClasses;

namespace CSRS.LLBLGenPro { class GeneralConcurrencyControl : IConcurrencyPredicateFactory { public IPredicateExpression CreatePredicate( ConcurrencyPredicateType predicateTypeToCreate, object containingEntity) { EntityBase2 entity = (EntityBase2)containingEntity; IPredicateExpression expression = new PredicateExpression();

        EntityFields2 timestampField = (EntityFields2) predicateTypeToCreate.GetType().InvokeMember("GetFieldsInfo", BindingFlags.InvokeMethod, null, predicateTypeToCreate, null); 

        switch (predicateTypeToCreate)
        {

            case ConcurrencyPredicateType.Save:
                expression.Add(((EntityField2)timestampField["ConcurrencyTimeStamp"]) == entity.Fields["ConcurrencyTimeStamp"].DbValue);
                break;
        }

        return expression;
    }
}

}

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 14-Jun-2008 08:20:26   

It seems to be ok wink Have you tested using DI yet?

Please let us know if you made it.

David Elizondo | LLBLGen Support Team
JieMa
User
Posts: 6
Joined: 09-Jun-2008
# Posted on: 17-Jun-2008 02:09:15   

all I need to do is to add following line into web.config file: <dependencyInjectionInformation> <additionalAssemblies> <assembly filename="....\XXX\bin\debug\XXX.LLBLGenPro.dll"/> <assembly fullName="XXX.LLBLGenPro, Version=1.0.0.0, Culture=null, PublicKeyToken=null"/> </additionalAssemblies> </dependencyInjectionInformation>

Question is, comparing between filename and fullName, which way do you prefer to use?

Walaa avatar
Walaa
Support Team
Posts: 14987
Joined: 21-Aug-2005
# Posted on: 17-Jun-2008 12:16:49   

I always use the filename approach. Sometimes this might not work, with a web-site project, then you would need to fall back to the fullname approach.

JieMa
User
Posts: 6
Joined: 09-Jun-2008
# Posted on: 02-Jul-2008 19:12:26   

OK, now we have problem to determine the execution order of the classes involved in DI.

For example, we have DI to do data validation and we have DI to do concurrency, we also have DI to do auditing.

Question is each DI has an assembly or classes associated to it. If we bind these assembly into project through DI, which one will be executed first? What is the criteria to define the execution order of these assemblies?

Jie Ma

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39774
Joined: 17-Aug-2003
# Posted on: 02-Jul-2008 21:44:30   

Assemblies aren't executed, instances of classes inside these assemblies are used for various purposes. So if you have an Auditor class in assembly A, and a validator in assembly B, the validator is used when validation is done, and the auditor is used when auditing actions are to be logged (calls from the framework).

So i.o.w.: there's no order of execution to be known, as there aren't 2 objects defined for the same thing on a single entity, i.e.: an entity doesn't have two auditors, but at most 1, similar to validators.

Frans Bouma | Lead developer LLBLGen Pro
JieMa
User
Posts: 6
Joined: 09-Jun-2008
# Posted on: 03-Jul-2008 19:07:51   

OK, thanks for your answer.

Problem we have right now is audit information will be saved into database and concurrency checking is through DI as well. Both of them are DI and we want to do currency checking while saving audit information.

Is there anyway we can follow?

Walaa avatar
Walaa
Support Team
Posts: 14987
Joined: 21-Aug-2005
# Posted on: 04-Jul-2008 11:40:18   

Do you mean you want concurrency checking on the Audit records?

If I'm not missing something, concurrency is used when saving a fetched entity to make sure the database record wasn't updated by someone else. But Audits are all about inserts, nothing to be modified.

i.o.w concurrency is about updates, and Audit only use inserts.