Monday, September 6, 2010

Simple maths can boost your app performance

Xaf provides methods in your controllers to enable you to customize the types that is using. I am speaking about the CustomizeTypesInfo method

internal class MyClass:ViewController {

    public override void CustomizeTypesInfo(DevExpress.ExpressApp.DC.ITypesInfo typesInfo)

    {

        base.CustomizeTypesInfo(typesInfo);

    }

}

The thing is that using such decoupled approach can be very dangerous and resource consuming.

Take the following example .

Say you have 10 classes and you want to customize 2 of them . You also want to decouple the customization logic.

Then you probably write one controller like

internal class MyController1:ViewController {

    public override void CustomizeTypesInfo(DevExpress.ExpressApp.DC.ITypesInfo typesInfo)

    {

        base.CustomizeTypesInfo(typesInfo);

        var type = typeof(Class1);

        foreach (var typeInfo in typesInfo.PersistentTypes.Where(info => info.Type==type)) {

            typeInfo.AddAttribute(new SomeAttribute());

        }

    }

}

and another one like

internal class MyController2:ViewController {

    public override void CustomizeTypesInfo(DevExpress.ExpressApp.DC.ITypesInfo typesInfo)

    {

        base.CustomizeTypesInfo(typesInfo);

        var type = typeof(Class2);

        foreach (var typeInfo in typesInfo.PersistentTypes.Where(info => info.Type==type)) {

            typeInfo.CreateMember("SomeName", typeof (SomeType));

        }

    }

}

the decoupling you wanted has as result to force the CLR to enumerate your typesInfo.PersistentTypes twice in order to apply your logic. And if you put that in real world your classes may be 500 and your logics 1000 that means 500x500 to apply 1000 logics!!! Its a big number and can slow you down for sure

Luckily that Xaf architecture can help us once more here!!! And to those that guess it already i am again speaking about the powerfull XafTypesInfo system.

So how to design the above to get max performance?

1st create 2abstract classes like

public abstract class LogicRegistrator {

    protected abstract void ExecuteCore(ITypeInfo typeInfo);

    public abstract void Execute(ITypeInfo typeInfo);

 

}

public abstract class LogicRegistrator<T> : LogicRegistrator

{

    public override void Execute(ITypeInfo typeInfo)

    {

        if (typeInfo.Type == typeof(T))

            ExecuteCore(typeInfo);

    }

}

then create 2 more classes for implementing your logics

public class Behaviour1:LogicRegistrator<Class1> {

    protected override void ExecuteCore(ITypeInfo typeInfo) {

        typeInfo.AddAttribute(new SomeAttribute());

    }

}

public class Behaviour2:LogicRegistrator<Class2> {

    protected override void ExecuteCore(ITypeInfo typeInfo) {

        typeInfo.CreateMember("SomeName", typeof(SomeType));

    }

}

and final step one controller that can handle all logics.

internal class MyController:ViewController {

    public override void CustomizeTypesInfo(DevExpress.ExpressApp.DC.ITypesInfo typesInfo)

    {

        base.CustomizeTypesInfo(typesInfo);

        var typeInfos = XafTypesInfo.Instance.FindTypeInfo(typeof(LogicRegistrator)).Descendants.Where(info => !(info.IsAbstract));

        foreach (var typeInfo in typeInfos) {

            var logicRegistrator = (LogicRegistrator) ReflectionHelper.CreateObject(typeInfo.Type);

            logicRegistrator.Execute(typeInfo);

        }

    }

}

That way your logic still remain decoupled at LogicRegistrator descenants and you not have to enumarate all persistent classes for each one of them.

ps: I did not calculate how much faster that would be cause the post was about simple maths :)

To be continued….

Subscribe to XAF feed
Subscribe to community feed

DiggIt!
blog comments powered by Disqus