Monday, December 20, 2010

eXpand gets a Russian ISBN

Continuing my effort to introduce eXpand framework to the world and with the help of some eXpand framework funs that want to remain anonymous I got invited to write an article for the Second International Scientific-Practical Conference Proceedings hosted at http://objectsystems.ru/ and edited by Pavel P. Oleynik

The title of my article is Application frameworks in the real world and in a few words I explain the idea behind eXpand framework, how we have extend Devexpress XAF framework and speak about eXpand architecture. The paper can be very useful to all XAF/eXpand users! (pages 9-15 English)

The collection can be found at Object Systems – 2010 (Winter session), The Second International Scientific-Practical Conference Proceedings, Russia, Rostov-on-Don, 10-12 November 2010. Edited by Pavel P. Oleynik

cert_ru

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, December 6, 2010

Context programming

I ll start this post with a phrase : WE HAVE TO REMEMBER TO NOT REINVENT THE WHEEL .

Why I say that?

XAF with the help of eXpand  is now a very mature framework. Almost all the tools required for build LOB applications are here. XAF has many ruling engines (Validation,EditorState,Appearence) and eXpand also the same (AdditionalViewControls, ModelArtifactState, MasterDetail, ConditionalDetailViews).

All the above engines provide a way to describe behaviors using rules and they operate over certain Contexts. What is a context some of you may ask. The answer is simple, context means the “when” the rule is going to be evaluated. For example Validation rules have 2 predefined contexts , those are Save,Delete.

I am going to give an example of how powerful a context is . Let say we have a Customer-Order relationship and we have 2 cases like the following

  • First record of Customer Orders cannot be deleted.
  • Only the last record of Customer Orders can be deleted

So what we need to design the above rules? First of all since both cases speak about the index of Order record we need to adjust our Order class to provide that info. If you use eXpand the code should be similar to

image

And the second step is to decorate the Orders collection of the Customer class with 2 RuleValueComparison attributes

image
As you see we have 2 rules that operate on the Delete context and check the value of the Sequence property against an Aggregation. That is a very powerful approach cause we used the Validation engine that is fully tested and we just describe our scenario declaratively using attributes. In fact we could do the same at runtime using the Model editor.

But let me add 2 more cases

  • Only the last record of Customer Orders can be cloned
  • Only the last record of Customer Orders can be edited

From a first look seems that validation engine cannot help us here, but if we think again we will notice that only the deleted word changed to cloned/edited. In other words only the context change so we could just add the “Cloned;Edited” context to our last rule

image

 

and write some code that will force the Validation engine to execute for our custom contexts as well.

image

 

The only caveat here is that you have to manually write the above code for every action you want to force the engine to run. But if you are using eXpand you not need the above handling, you could just use the Ids of your actions as Context names and eXpand will force the validation engine to execute

image

 

The above code can be used with eXpand 10.2.3 or newer and is hosted at eXpand.ExpressApp.Validation module

http://expandframework.com/download.html

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Thursday, December 2, 2010

Modular User interface

I was discussing with a friend some days ago about his project requirements.

  • Solution had roles but they where fixed (Like Manager, Receptionist etc)
  • Different UI is needed for each role
  • At runtime there should be a way to change the UI using an action

He told me that he was aware of eXpand Role models and he thought that they could help his case.

For those of you that are XAF newbies a XAF model is really a description of your application structure /behavior over a xafml file

Sure I told him ModelDifference module can help , however the approach would be slightly different from the one you had in your mind and here is why:

Although the application have roles since there is no login (wanted to change UI from an action ) we could not use ModelDifference Role models.  What I suggested was to use disabled application models and then use eXpand api to just enabled them at runtime. In fact we could create as many application models as the fixed roles are in the updater with a code similar to

    public class Updater : ModuleUpdater {

        public Updater(Session session, Version currentDBVersion) : base(session, currentDBVersion) { }

        public override void UpdateDatabaseAfterUpdateSchema() {

            base.UpdateDatabaseAfterUpdateSchema();

            CreateDisabledModelDifferenceObject(typeof(ManagerModelStore));

            CreateDisabledModelDifferenceObject(typeof(ReceptionistModelStore));

        }

 

        void CreateDisabledModelDifferenceObject(Type storeBaseType) {

            var modelDifferenceObject = Session.FindObject<ModelDifferenceObject>(o => o.Name == storeBaseType.Name);

            if (modelDifferenceObject == null) {

                ModelDifferenceObject differenceObject = new ModelDifferenceObject(Session).InitializeMembers(storeBaseType.Name);

                var layer = new ModelApplicationBuilder(differenceObject.PersistentApplication.ExecutableName).GetLayer(storeBaseType);

                differenceObject.CreateAspects(layer);

                differenceObject.Disabled = true;

                differenceObject.Save();

            }

        }

    }

 

also we need 2 modelstores that will point to our Manager,Receptionist models

 

    public class ReceptionistModelStore : ModelApplicationFromStreamStoreBase {

        protected override Stream GetStream() {

            return GetType().Assembly.GetManifestResourceStream(GetType(), "Receptionist.xafml");

        }

    }

    public class ManagerModelStore : ModelApplicationFromStreamStoreBase {

        protected override Stream GetStream() {

            return GetType().Assembly.GetManifestResourceStream(GetType(), "Manager.xafml");

        }

    }

  

2 design time models Manager.xafml,Receptionist.xafml

image

 

of course eXpand Model Editor addin in order to be able to modify the models

image

 

The code we wrote at the update will create 2 disabled application models in our modeldifference listview as shown bellow

image

Disabled models means that they wont load when application starts. In order to load them on demand we have to create some actions and use ModelDifference api. A simple controller like the one bellow will do the job.

 

using DevExpress.ExpressApp;

using DevExpress.ExpressApp.Actions;

using DevExpress.ExpressApp.Win;

using DevExpress.Persistent.Base;

using Xpand.ExpressApp.ModelDifference.Core;

 

namespace Solution1.Module.Win {

    public class ActionsController : ViewController {

 

        public ActionsController() {

            var managerAction = new SimpleAction(this, "Manager", PredefinedCategory.View);

            managerAction.Execute += ManagerActionOnExecute;

            var receptionistAction = new SimpleAction(this, "Receptionist", PredefinedCategory.View);

            receptionistAction.Execute += ReceptionistActionOnExecute;

        }

 

        void ReceptionistActionOnExecute(object sender, SimpleActionExecuteEventArgs simpleActionExecuteEventArgs) {

            var modelApplicationLoader = new ModelApplicationLoader();

            modelApplicationLoader.EnableModel(o => o.Name == "ReceptionistModelStore", new[] { "ManagerModelStore" });

            RecreateWindows();

        }

 

        void ManagerActionOnExecute(object sender, SimpleActionExecuteEventArgs simpleActionExecuteEventArgs) {

            var modelApplicationLoader = new ModelApplicationLoader();

            modelApplicationLoader.EnableModel(o => o.Name == "ManagerModelStore", new[] { "ReceptionistModelStore" });

            RecreateWindows();

        }

 

        void RecreateWindows() {

            var showViewStrategyBase = (WinShowViewStrategyBase)Application.ShowViewStrategy;

            showViewStrategyBase.CloseAllWindows();

            showViewStrategyBase.ShowStartupWindow();

        }

    }

}

and that was it!!
The above solution needs eXpand v10.1.8 or newer http://expandframework.com/download.html

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Tuesday, November 16, 2010

Converting Lambda expressions at runtime

DevExpress XPO as all modern ORM supports object querying using linq and lamda expressions. A sample query can be written as

            var xpQuery = new XPQuery<Customer>(Session.DefaultSession);

            IQueryable<Customer> customers = xpQuery.Where(customer => customer.Age == 25);

 

From the above query we can get a list of customers that are 25  years old . As you can see the code is very simple.

The problem 
When working with modularized applications you may be in context that you have access to the Customer type  only at runtime or you may want to apply that query to different object types that all have an Age property. How that can be done?

1st attempt

Lets register the customer to our module and use reflection to create the XPQuery.

            ModuleXXX moduleXxx = new ModuleXXX();

            moduleXxx.DoQuery(typeof (Customer));

 

and the DoQuery method will be something like

 

        public void DoQuery(Type customerType) {

            Type makeGenericType = typeof (XPQuery<>).MakeGenericType(customerType);

            object xpQuery = Activator.CreateInstance(makeGenericType, new object[] {Session.DefaultSession});

            //THIS IS A DEAD END

            //although we can construct the XPQuery object we have to stop here cause there is no way to use it since we not have the type at design time

        }

 2nd Attempt

Refactor our customer using an ISupportAge interface that will live in our module and use that interface with the DoQuery method

    public interface ISupportAge {

        int Age { get; set; }

    }

 

    public class Customer : BaseObject, ISupportAge {

        public Customer(Session session) : base(session) {

        }

        private int _age;

        public int Age {

            get {

                return _age;

            }

            set {

                SetPropertyValue("Age", ref _age, value);

            }

        }

    }

 

Now the DoQuery will have no arguments

 

            ModuleXXX moduleXxx = new ModuleXXX();

            moduleXxx.DoQuery();

 

and will look like

 

        public IQueryable<ISupportAge> DoQuery() {

            var xpQuery = new XPQuery<ISupportAge>(Session.DefaultSession);

            return xpQuery.Where(customer => customer.Age == 25);

        }

 

as you see in the code above in order to be able to use lamda expressions i have passed the ISupportAge interface in my XPQuery method. Too bad that XPQuery supports as generic parameters only persistent types and not interfaces

 

3rd Attempt

The previous attempt was pretty closed to what we wanted. Brainstorming and researching a little more we can find that lambda expressions are fully decomposable. That means that they consist of parts like body,parameters,sub expressions that can be decomposed and recomposed again. After decomposing the tree using Xpand.Utils.Linq.ExpressionConverter the DoQuery method now will  look similar to

 

        public IQueryable<ISupportAge> DoQuery(Type customerType) {

            //here we create a lambda based on the ISupportAge interface

            Expression<Func<ISupportAge, bool>> expression = date => date.Age == 25;

 

            //Convert the lambda using the customerType argument the new expression will be of type Expression<Func<Customer, bool>>

            //but since our method knows nothing about customer we have used the abstract Expression type.

            Expression convert = new ExpressionConverter().Convert(customerType, expression);

 

            //create the Xpquery instance

            Type xpQueryGenericType = typeof(XPQuery<>).MakeGenericType(new[] { customerType });

            object xpquery = Activator.CreateInstance(xpQueryGenericType, new[] { Session.DefaultSession });

 

            //find the where method

            MethodInfo mi = typeof(Queryable).GetMethods().Where(info => info.Name=="Where").FirstOrDefault();

            mi = mi.MakeGenericMethod(customerType);

 

            //execute the where but now using the converted lambda

            return ((IEnumerable)mi.Invoke(xpquery, new[] { xpquery, convert })).OfType<ISupportAge>().AsQueryable();

        }

 

You can find the ExpressionConverter at eXpand source code avalibale at http://expandframework.com/download.html

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Wednesday, November 3, 2010

DevExpress interviewed eXpand framework

Rachel Hawley from DevExpress interviewed me over expand some days ago. You can read more at her blog

eXpand: An open source framework built with XAF

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, November 1, 2010

Runtime Orphaned Collections

eXpand already provided support for various runtime member scenarios such as

Calculated properties at runtime—TIMES 4
Dynamic Types with WorldCreator source code is out

In the post I am going to speak about our latest addition which is support for runtime orphaned collections.

Using Model Editor

As you see in the image bellow you only have to create a new IModelRuntimeOrphanedColection image

set CollectionType attribute (1)

image

and filter the collection by using the criteria (2).

Although the Model Editor approach with a combination of the ModelDifference module can provide great flexibility such as defining Runtime Collections for a set of Roles or Users has a drawback. It does not add those collections in any of your views. You have to do that manually.

Using WorldCreator Extended Classes

This approach overcomes the previous Model Editor drawback, since the runtime collections are created before the model. Hence your runtime collections are added to all related views

 image

As you saw in the above images that functionality is demoed at eXpand feature center http://expandframework.com/download.html

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Tuesday, October 26, 2010

Controlling DevExpress Xtratreelist control

Keeping our promises eXpand team is happy to announce more control over the DevExpress XtraTreelist. We have use eXpand dynamic model creation feature to map all options of the XtraTreelist control to the model. The process used is very similar to the one used for

Controlling DevExpress XtraGrid Control at runtime
Controlling DevExpress AspxGridControl at runtime
Controlling DevExpress XtraGrid Part-3 (The Columns)

and we renew our promise to map more controls in the future versions

image

image 

image

Bonus Feature

Applying the familiar techniques of the Conditional Appearance module is now possible for a TreeListEditor

image

image

Both features above require to change the Default EditorType to Xpand.ExpressApp.TreeListEditors.Win.ListEditors.XpandTreeListEditor as shown in the image

image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, October 11, 2010

Let your business users develop for you

At November 27-28 one of the biggest IT events ITPro & Dev Connections will take place in Athens. I am invited to speak over Xaf / eXpand and I will speak over the post subject: “Let your business users develop for you” (14:15-15:30). If you plan to be in Athens in that time and you like to come to the event, I suggest you secure your seat now cause as far as I know they are only few of them left

Short description of my speech

Definition of Garbage Code can be consider any code that project specific and your company cannot reuse

The solution would be to make that code configurable/ declarative and push it back to your reusable framework. You will learn all about Xaf architecture, you will see how much Xaf by default can achieve the previous by describing your domain and UI over a model, and how the open source framework our team is developing takes it to another level.

For those of you that will attend, DevExpress is sponsoring my speech with one license of DXperience Universal!!!

PS: If you want me to present anything XAF /eXpand related to your local .NET user group do not hesitate to contact me

Agenda

Building a Business Solution

  • Following the typical pattern (6 Steps)
  • Xaf implementation of the typical pattern (2 Steps)
  • eXpand declarative world!!! (FeatureCenter)
    • Models
      • Application, Role, User models creation-upcasting-modyfication
      • Combining and associate with permissions
      • Handling external Models
    • Dynamic Persistent Assemblies
    • Connecting to external databases (eg.ERP)
    • IO mechanism
    • Extending Models by Applying Design Patterns
      • Runtime Interfaces
      • Building conditional modules
  • QA

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, October 4, 2010

eXpandFramework v10 released

Our team is happy to announce a stable v10 version for windows platform. In order to help the community adopt expand further we have publish an expand dedicated site at www.expandframework.com . Forums are available also for discussion over various cases at http://expandframework.com/forum.html

A big thanks to our sponsors http://expandframework.com/sponsors.html (only 5 for now :) but we expect more), all are happy to provide a pro license to anyone that is interested to help building expandframework. Also our team is building a wiki over our new site , so if you have modules, controllers, ideas , want to be a dedicated wiki writer or you want to actively help expandframework development please write us at contribitors@expandframework.com .

You can find the latest nightly builds at our download section http://expandframework.com/download.html where sources and binaries are available.

Along with the framework a FeatureCenter application has been released. FeatureCenter is developed having in mind to present features decoupled, so it is very easy to get the most our of it. Our suggestion to get the most out of it goes as following:

First run Featurecenter, first time load will be slow cause creates many datastores(5 for now) and imports a lot of data. Then navigate through the menu system and see a feature you are interested in eg. Grid Column Options

image

First you read the nodes over the feature that are available for each view .
image

Then if model differences have been applied to the view to enable /configure the feature a special action will be enabled as you see in the next image

image

executed and note the differences as shown to understand what model modification are needed in order the feature to work.

image

and as last step you can use your Visual studio Solution explorer to navigate at the same path as the navigation menu to see the design time of the feature.

image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Tuesday, September 28, 2010

Calculated properties at runtime—TIMES 4

In this post you are going to see how you can use on more of eXpand powerfull features. 4 different ways for creating calculated runtime properties are avaliable.

  1. XPO way –>Using Code
    Take a note at the CreateCalculabeMember extension method at the code bellow

        public class CreateRuntimeCalculatedFieldController : ViewController {

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

                base.CustomizeTypesInfo(typesInfo);

                var classInfo = XafTypesInfo.XpoTypeInfoSource.XPDictionary.GetClassInfo(typeof(Customer));

     

                if (classInfo.FindMember("SumOfOrderTotals")==null) {

                    var attributes = new Attribute[] {new PersistentAliasAttribute("Orders.Sum(Total)")};

                    classInfo.CreateCalculabeMember("SumOfOrderTotals", typeof(float), attributes);

                    typesInfo.RefreshInfo(typeof(Customer));

                }

            }

        }

  2. Using ModelDifference Module
    Setting IsRuntimeMember attribute will create a runtime member and setting the AliasExpression will convert it to a calculated member
    image
    Take a note here that you can easily create calculabe members for the whole application or for a user role or for just one user, depending which type of model is going to host your property
  3. Using WorldCreator extended members
    This approach can be used when u want to decorate your property with more attributes , since WorldCreator  supports much more than the model
    image image
  4. Using a WordCreator Dynamic Assembly
    this approach is the most powerfull one cause allows you also to change the code template as you see in the image bellow

    image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Wednesday, September 22, 2010

Model Distribution with IO Engine

ModelDifference module is one of the powerfull modules of eXpand . It really helps in managing your application models.

Scenario
Your application has been already distributed to your client and you no longer have access to the production database. Your client admin is responsible for that. But since development never stops as you know, you client asked for some model modification and some new application models (lets say 10) have been developed by your team and you want to sent them to the admin to update the application.

eXpand IO module is the right one for the job

Step1—Create a serialization graph to configure which objects/values you are going to export

In order to create a serialization graph for an object type you have 1st to create a Serialization Configuration Group, that is just a container to help you organize your graphs

image

Given that you want to export Models you have to create a graph for the ModelDifferenceObject persistent class

image

When you set the Type To Serialize editor value (1) IO module will automatically fill the values of the nested listview (2) by populating the properties of the Application Difference object, and also will create graphs for objects that are connected with Application Difference object (3)

Step2--Clean automatically created graph

You may wondering how the graphs in the number (3) of the above image are created. If you see the domain model of the ModelDifferenceObject you will see the relation between all these objects.

image

So what IO module does goes through all those relations and create graphs for each one of them, since due to object polymorphism it is impossible to know the type of the object from the start. But you do!! You know that you are interested to export only ModelDifferenceObjects and not RoleModelDifferenceObject or UserModelDifferenceObject so you could delete all other graphs as showh bellow

image

Step3—Choose Serialization Strategy

This screenshot are taken from eXpand feature center and as you see there are some properties that we may not want to export such as City,UserFilter,Skin. We can exclude them from the export process by choosing a DoNotSerialize strategy

image

Now for the  most interesting and hard step. As you see from the domain model above ModelDifferenceObject has M-1 relation with the PersistentApplication object, also by the name of PersistentApplication one can understand that the already distributed application already have that object and we not want to export its properties but only its key, so choosing a SerializeAsValue strategy will solve that one also

image

But we have not finish yet. If you think again what we did is export only the key of the PersistentApplication, but the key type is GUID meaning that the distributed application with the one from the which we are going to export will have different keys. To solve this one we have to go to the PersistentApplication Graph and change the key from Oid to UniqueName, thus IO engine will not get confused and will used the appropriate object

image

image

Step4 –Select and export models

Just go to a list view that has the objets you are interested to export and use the IO/Export action

Step 5—Import the exported objects

This process is very easy and only requires to use the IO/Import action and choose the xml file .

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, September 20, 2010

Make your navigation behave

Xaf provides a very easy to configure navigation system and in this post i will speak about expand approach to make Xaf’s navigation system behave better than the one provided by default.

To enable eXpand extended navigation behaviour one can use the ViewShortcutProccesor attribute either at BO level or at View level as shown in the next image

image image

Now what this ViewShortcutProccesor can do to speed up your development?

  1. Navigate to a detailview using a ReadOnlyParameter

    image

    the above readonly parameter taken from eXpand feature center and is defined as

        public class ExternalApplicationKeyParameter : ReadOnlyParameter

        {

            public ExternalApplicationKeyParameter() : base("ExternalApplicationKey", typeof(Guid)) { }

     

            public override object CurrentValue {

                get {

                    return ((User) SecuritySystem.CurrentUser).Session.FindObject<ModelDifferenceObject>(

                            o => o.Name == "ExternalApplication" && o.PersistentApplication.Name == "ExternalApplication").Oid;

                }

            }

        }

     

  2. Navigate to a non persistent object detail view
    image
    the object can be designed as

        [NonPersistent]

        public class WelcomeObject

        {

        }

    or as

        [NonPersistent]

        public class WelcomeObject:XPBaseObject

        {

            public WelcomeObject(Session session) : base(session) {

            }

        }

  3. Browse objects directly from a detailview
    The navigation settings here are exaclty the same as the above but also the navigation actions of the detailview will be enabled, allowing you to navigate to the next record.
    if for the current type no objects are found a new one will be created
    image
  4. Navigate to a specific object/ collection of objects detailview
    Setting at ObjectKey the criteria of your choice  you can open a directly a detailview. If object not found a new one will be created again
    image
  5. Desing your navigation using class based attributes
    Using XpandNavigationItem you can design deep tree level menus by just decorating your class
    image
    the above declaration will create the navigation shown in the image bellow
    image
  6. Design time view cloning
    When building a real world application, most probably you are going to have multiple views for your object types. eXpand provides the CloneView class level attribute that can help you create cloned views at design time.

        [CloneViewAttribute(CloneViewType.ListView, "ConditionalControlAndMessage_ListView")]

        public class Customer : CustomerBase {

            public Customer(Session session) : base(session) {

            }

     

        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]

        public class CloneViewAttribute : Attribute, ISupportViewId {

            readonly CloneViewType _viewType;

            readonly string _viewId;

     

            public CloneViewAttribute(CloneViewType viewType, string viewId) {

                _viewType = viewType;

                _viewId = viewId;

            }

     

     

            public string ViewId {

                get { return _viewId; }

            }

     

     

            public CloneViewType ViewType {

                get { return _viewType; }

            }

     

            public string DetailView { get; set; }

        }

     

    the advantage of using CloneViewAttribute is that your cloned views are not created in the lastlayer, thus later changes on the view are noted easily . As you see in the next image only the NewColumn attribute is mark bold!!
    image 

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Wednesday, September 15, 2010

Conditional Member Level Security

DevExpress has the best support center I have ever seen, their Code Central really rocks and its fill with hundredths' of samples. One of them is is

How to implement the MemberLevel security manually (for example, to deny the 'Read' access for declared properties of some business class, and allow access for the inherited properties

eXpand has the above example as a module since its version 9 and you can use it by using the Xpand.ExpressApp.MemberLevelSecurity.dll assembly following the standard procedure for registering a xaf module.

But in v10 we have boost it a little bit and we have make it conditional so now you can apply multiple Member Access Permissions to a member

image

and by using the criteria member you can force the permission to be applied only to objects that fit those criteria

image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, September 13, 2010

Non constant attributes parameters?

Given my previous post

Simple maths can boost your app performance

did some more thoughts over it in this post 

.Net compiler says no!!

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type   

public class CustomAttribute:Attribute {

    public CriteriaOperator CriteriaOperator { get; set; }

 

    public CustomAttribute(CriteriaOperator criteriaOperator) {

        CriteriaOperator = criteriaOperator;

    }

}

[CustomAttribute(CriteriaOperator.Parse("Name=?","eXpand"))]

public class Class1 {

 

}

the above cannot be compiled

BUT XAF SAYS YES

Why? Cause it has its own type system the XafTypesInfo system. And the types are added it to it at runtime. Meaning? We can do anything!!!

Take for example the following implementation of the above

core classes

public class MyController:ViewController {

    public override void CustomizeTypesInfo(ITypesInfo typesInfo)

    {

        base.CustomizeTypesInfo(typesInfo);

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

        foreach (var typeInfo in typeInfos) {

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

            foreach (var attribute in logicRegistrator.GetAttributes(typeInfo)) {

                typeInfo.AddAttribute(attribute);

            }

        }

    }

}

 

public abstract class AttributeRegistrator {

    public abstract IEnumerable<Attribute> GetAttributes(ITypeInfo typesInfo);

}

implemention

public class CustomAttributeRegistrator:AttributeRegistrator {

    public override IEnumerable<Attribute> GetAttributes(ITypeInfo typesInfo) {

        if (typesInfo==typeof(Class1))

            yield return new CustomAttribute(CriteriaOperator.Parse("Name=?", "eXpand"))

    }

}

Cause modern programming is based on attributes the AttributeRegistrator example is most usefull when for example multiple developers wan to to work on the same class, the example was stolen from eXpand featurecenter application were that case is valid :) (Many developers work on the same file)

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Wednesday, September 8, 2010

ERP to XAF connection on the fly part1

There is a new kid on the block called DBMapper that obsoletes SqlDBMapper. DBMapper has the same functionality as SqlDbMapper however is based on the powerful XPO . Thus  DBMapper module is capable of transforming into WorldCreator persistent classes the following list of databases: Access, AdvantageAdaptive Server Anywhere, Ase, DB2FireBirdFireBirdSqlSqlServerCeSqlServerODP
OraclePersasizeSqlPostgreSqlSQLiteVistaDB
Some years ago (before Xaf was born) you have bought an ERP for your company and you are not satisfied with its Analysis,Reporting,PIvoting,Sceduling etv capabilities and you wish the creator of your ERP to have use Xaf instead.
If you are looking for the easiest way to map your ERP database into a Xaf application expand framework has the solution for you its called WorldCreator SqlDBMapper module. That module can map any Sql server database into a Xaf application. Bellow I demo how you can use it.
Create an empty eXpand solution
image
or use an existing one and navigate to the persistent assembly listview
image
create a new persistent assembly info object, for the sake of the demo i will map NorthWind database,
image
Use the Tools/Map Database action
image
to connect to a database
image
assign the default navigation path where your the generated classes want to appear in the navigation menu
image
The above actions will generate persistent classes that will map the exact schema of any sql database (all relations/types are supported)
It will also produce the code of the classes and you may copy it and add it to your solution and not use the runtime version of them
image
After restarting the application eXpand will compile that code and load it as Xaf module , It will also connect to the database allowing you to modify/analyze its data. Also an assembly will be created at the application directory for further use with the name NorthWind.expand
Final the navigation items in the path you set above (WorldCreator/NorthWind)
image
and you are ready !!!

Subscribe to XAF feed
Subscribe to community feed

DiggIt!