Παρουσίαση με Ετικέτες

XAF: Soft Validation (What’s New in 13.2)
28 Νοεμβρίου 13 05:50 πμ | tolisss | 0 σχόλια   

Our next major release (13.2), updates our Validation Module with more features that come with different behavior rules, such as Warnings and Information. These can be applied to your existing validation rules using code or the Model Editor.

The XAF validation module is a mature and flexible validation system, which allows you to create rules that can validate any business problem, For more information, check out the module documentation.

Suppose we have a Business Object that disallows saving a Customer if the Name property is blank. If this attempted the UI should respond with a “Everybody has a name!” message.

[DefaultClassOptions]

public class Customer : BaseObject {

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

    [RuleRequiredField("Customer_Name_Required", DefaultContexts.Save, "Everybody has a name!")]

    public string Name { get; set; }

    public string City { get; set; }

    public int Age { get; set; }

}

When an end user tries to save the Customer without a name, XAF will show the Validation Error listview and consequently abort.

image

Creating a warning rule

A common requirement for our Customer class is to warn the end user that, if possible, he/she should provide the Customer’s city. To do this, we need to mark the City property with a  RuleRequiredField. However, this time we have to set the ResultType to Warning as illustrated below.

[DefaultClassOptions]

public class Customer : BaseObject {

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

    [RuleRequiredField("Customer_Name_Required", DefaultContexts.Save, "Everybody has a name!")]

    public string Name { get; set; }

    [RuleRequiredField("Customer_City_Warning", DefaultContexts.Save, "Provide the City if possible",

        ResultType = ValidationResultType.Warning)]

    public string City { get; set; }

    public int Age { get; set; }

}

When the end user saves the Customer (in runtime) providing a Name and not a City, XAF will again show the Validation Error listview however, this time there will be an extra Ignore action.

image

If the end user executes the Close action, the object will not be saved however if he executes the Ignore action it will be saved. In both cases in the detailview there will be a warning action by the City textbox to draw the end user’s attention.

image

Creating an Information rule

XAF allows you to create validation rules even at runtime using the Model Editor. So let’s say we want to just inform the end user, if he enters a Customer Age not between 10 and 60. This means that we need to use a RuleRangeField rule as illustrated in the next two images.

image

image

When the end user saves a Customer (in runtime) with an invalid Age range, XAF will not display the Validation Error listview at all. However, it will display an Information icon to draw his/her attention to the Age property.

image

Where to see more examples?

You may explore our FeatureCenter application located in your C:\Users\Public\Documents\DXperience 13.2 Demos\eXpressApp Framework\FeatureCenter\CS folder to see a few rules in action.

What about the web?

The validation module as a platform agnostic module works similarly for the web.

image

The soft validation is in its first release (CTP), thus we look forward to your feedback as we get it ready for it’s official release. Let me know what you think.

Δημοσίευση στην κατηγορία: , , ,
Creating a State Machine module for eXpand Framework–Part 2
23 Σεπτεμβρίου 11 03:52 πμ | tolisss | 0 σχόλια   

Prerequisites
Part 1

In this post we are going to enhance the State Machine module UI. Remember that along with all the usual XAF goodies we can now use Xpand code base which gives us a lot more options. Our StateMachineTransitionPermission has 2 lookups, StateMachineName and StateMachine. Our goal is to populate both of these cascading lookups without creating a platform specific module.

StateMachineNames

Creating lookups is a common scenario for which Xpand provides a set of property editors and controllers. By contrast with other business frameworks XAF allows maximum flexibility. Therefore in most cases we are able to code in such a generic way that everything could live in separate frameworks such as eXpand. Now, in order to populate the StateMachine name I am going to derive a new controller from a specialized abstract controller which is Xpand.ExpressApp.SystemModule.PopulateController<T>. This controller uses the PredefinedValues attribute of the XAF model. When filling the attribute with a set of values separated by semicolons XAF will create a lookup with these values targeting each supported platform.

image

However, if at runtime we set the value of the PredefinedValues attribute this will be written at model’s lastlayer and it will make it dirty. We want to avoid this because we want to leave the lastlayer intact.. To cater for this need the populate controller uses a hack. First it stores the lastlayer in a variable then removes it from the model’s layers collection. As a result it is possible to modify the new lastlayer as shown in the Populate method and then return the clean old one to its place. Now the model has all the necessary information with a clean userdiffs layer and while XAF is creating a new view can get the PredefinedValues string from it and create the lookups.

public abstract class PopulateController<T> : ViewController<ObjectView> {

   

    …

 

    protected virtual void Populate(Func<IModelMember, string> collect) {

        var name = PropertyName;

        if (name != null) {

            var model = ((ModelApplicationBase)Application.Model);

            var lastLayer = model.LastLayer;

            model.RemoveLayer(lastLayer);

            PopulateCore(collect, name);

            model.AddLayer(lastLayer);

       }

   }

 

    private void PopulateCore(Func<IModelMember, string> collect, string propertyName) {

        IModelMember modelMember = View.Model.ModelClass.AllMembers.FirstOrDefault(member => member.Name == propertyName);

        if (modelMember != null) {

            modelMember.PredefinedValues = collect.Invoke(modelMember);

        }

    }

    …

    …

   }

 

Although this seems like a complicated explanation users need not be intimidated! The implementation of our controller that will populate all StateMachineNames is as simple as this,

public class StateMachinePopulateController : PopulateController<StateMachineTransitionPermission> {

    protected override string GetPredefinedValues(IModelMember wrapper) {

        IList<XpoStateMachine> xpoStateMachines = ObjectSpace.GetObjects<XpoStateMachine>(null);

        return xpoStateMachines.Select(machine => machine.Name).AggregateWith(";");

    }

 

    protected override Expression<Func<StateMachineTransitionPermission, object>> GetPropertyName() {

        return permission => permission.StateMachineName;

    }

}

 

The first thing we did was to provide the propertyName in the GetPropertyName method. Then using the GetPredifinedalues method we return the semincolon delimited string with the machine names. This very simple controller is capable of populating the statemachine lookup for win and web platforms!.
 
StateCaptions
This is a cascading lookup and as a result when the current StateMachineName changes it needs to provide a list of all its StateCaptions. To this end we are going to use a specialized property editor, Xpand’s StringLookupEditor. This supports the DataSourceProperty XAF attribute which will be used to provide the StateCaption collection. Moreover when using Xpand it is possible to mark editors with an interface and host it in a transparent module. We can then use the Xpand PropertyEditor attribute with the type of the interface as parameter to tell XAF which propertyeditor will be created at runtime. Finally we need to apply all these along with an ImmediatePostData to the StateMachineName property. The permission will look like this,
 

[ImmediatePostData]

public string StateMachineName { get; set; }

 

//IStringLookupPropertyEditor lives in Xpand.ExpressApp assembly

//Xpand.ExpressApp.Web.PropertyEditors.StringLookupPropertyEditor, Xpand.ExpressApp.Win.PropertyEditors.StringLookupPropertyEditor inherit from IStringLookupPropertyEditor

[PropertyEditor(typeof(IStringLookupPropertyEditor))]

[DataSourceProperty("StateCaptions")]

public string StateCaption { get; set; }

 

IList<string> _stateCaptions = new List<string>();

[Browsable(false)]

public IList<string> StateCaptions {get {return _stateCaptions;}}

 

If you look carefully at this code however you may notice that __stateCaptions count is always zero. Let me remind you here that the StateMachineTransitionPermission is a non persistent sessionless object. This means that the object is not handled by an ObjectSpace therefore a call like ObjectSpace.FindObjectSpaceByObject(this) will always return null. In addition the permission does not implement INotifyPropertyChanged so we need to synchronize the class just before the StateCaptions are requested. Below you can see a modified version of the StateMachinePopulateController,

 

public class StateMachinePopulateController : PopulateController<StateMachineTransitionPermission> {

    protected override void OnViewControlsCreated() {

        base.OnViewControlsCreated();

        var stringLookupPropertyEditor = GetPropertyEditor(permission => permission.StateCaption) as IStringLookupPropertyEditor;

        if (stringLookupPropertyEditor != null)

            stringLookupPropertyEditor.ItemsCalculating += StringLookupPropertyEditorOnItemsCalculating;

    }

    void StringLookupPropertyEditorOnItemsCalculating(object sender, HandledEventArgs handledEventArgs) {

        var propertyEditor = GetPropertyEditor(permission => permission.StateMachineName);

        if (propertyEditor != null && View.IsControlCreated) {

            var stateMachineTransitionPermission = ((StateMachineTransitionPermission)View.CurrentObject);

            var readOnlyCollection = GetStateCaptions(propertyEditor);

            stateMachineTransitionPermission.SyncStateCaptions(readOnlyCollection, propertyEditor.ControlValue as string);

        }

    }

 

    ReadOnlyCollection<string> GetStateCaptions(PropertyEditor propertyEditor) {

        var stateMachineName = propertyEditor.ControlValue as string;

        return ObjectSpace.GetObjects<XpoState>(state => state.StateMachine.Name == stateMachineName).Select(

                state => state.Caption).ToList().AsReadOnly();

    }

 

Finally we add the new SyncStateCaptions method and the full version of the permission will be,

 

[NonPersistent]

public class StateMachineTransitionPermission : PermissionBase {

    …

    …

 

    [ImmediatePostData]

    public string StateMachineName { get; set; }

 

    [PropertyEditor(typeof(IStringLookupPropertyEditor))]

    [DataSourceProperty("StateCaptions")]

    public string StateCaption { get; set; }

 

    IList<string> _stateCaptions = new List<string>();

    [Browsable(false)]

    public IList<string> StateCaptions {get {return _stateCaptions;}}

 

    public void SyncStateCaptions(IList<string> stateCaptions, string machineName) {

        StateMachineName = machineName;

       _stateCaptions = stateCaptions;

    }

}

To support platform independent cascading lookups we wrote only about 10 lines of code! This is proof of how much XAF architecture cuts down on development costs. The module can be downloaded from the Xpand download page   and we are happy to hear your feedback. Remember that your questions are the best candidates for future posts!


Δημοσίευση στην κατηγορία: , ,
eXpandFrameWork Supporting Unbound Columns
16 Σεπτεμβρίου 11 09:46 πμ | tolisss | 0 σχόλια   

Recently in Xpand forums Dionisis Soldatos raised a question about how unbound columns can be implemented with XAF. Unbound columns along with their UnboundExpression can be used for creating calculated fields even at runtime. Since we are talking about unbound grid columns it should be obvious that we will operate at the UI level by modifying the grid control columns. However lets do a deep dive inside XAF model to extend it as needed!

The Model

By now we are all used to XAF providing us with excellent out of the box solutions which negate the need for us to write hundredths of lines of code. This of course means money saved during developing and ultimately your product hits the market faster. Why spend time reinventing the wheel when the XAF team have already done the hard work for you?

XAF creates the model by reading the metadata of our classes, this model has 3 types of view. One of these is the ListView which can be displayed with data source enabled controls like Grid controls. ListView has columns which correspond to existing object properties metadata and when XAF creates a Grid at runtime it queries model’s ListView columns. It then creates and configures Grid columns from their attributes. These stages are well tested and it is preferable to use them in our solution and override the unnecessary stages. For example we could create a normal model column node using XAF default Add/Column menu. After the Grid column is created it we simply need a few lines of code to make it unbound and set its Unbound Expression.

image

In order to store this expression we still need to extend model’s ListView with an attribute. The model can be extended either by registering an interface at ModuleBase.ExtendModelInterfaces or by deriving it from an already registered interface. I am going to take the latter options by deriving from IModelColumn interface which I will explain as we go.

public interface IModelColumnUnbound : IModelColumn {

[Category("eXpand")]

bool ShowUnboundExpressionMenu { get; set; }

[Category("eXpand")]

[Required]

string UnboundExpression { get; set; }

}

XAF model editor is a highly sophisticated tool which has the capability to recognize that we extended the model. It then takes care of the vital step of adding an entry to the Add menu for creating Unbound columns.

image

Now it is possible to create a new type of column with 2 extra attributes as shown,

image

Moving on we need to set the mandatory PropertyName attribute shown above to an always existing object property name. Remember XAF requires this in order to behave as designed. To this end we are going to set as PropertyName the object’s key property name using this simple DomainLogic class,

[DomainLogic(typeof(IModelColumnUnbound))]

public class IModelColumnUnboundLogic {

public static string Get_PropertyName(IModelColumnUnbound columnUnbound) {

return ((IModelListView)columnUnbound.Parent.Parent).ModelClass.KeyProperty;

}

As a result (PropertyName, PropertyEditorType and Caption) attributes will be populated the next time we create a ColumnUnbound Node. However these will be fixed values and it is preferable to hide them from the end user. At the same time we need to mark Caption attribute as required and remove its default value. To do all of this we just need to extend our IModelColumnUnbound interface like this,

image

Note; Although PropertyName and Caption belong to IModelColumn using the new operator it is possible to override them!

We have now finished with the model modifications and for our ColumnUnbound nodes XAF by design will create a new column pointing back to object’s key property metadata.

The UI

A key benefit of XAF’s commitment to design patterns, specifically to the Single responsibility principle, is that it provides us with the model’s synchronizer classes. These can be used to synchronize our model with the control and vice versa. It is only necessary to derive from the abstract ModelSyncroniser<T,V> and implement ApplyModeCore method to synchronize the control and from SynchronizeModel to do the same with the model.

public class UnboundColumnSynchronizer: ModelSynchronizer<GridListEditor, IModelListView> {

public UnboundColumnSynchronizer(GridListEditor control, IModelListView model)

: base(control, model) {

}

protected override void ApplyModelCore() {

var xafGridColumns = GetXafGridColumns();

foreach (var column in xafGridColumns) {

var modelColumnUnbound = (IModelColumnUnbound)column.Model;

column.FieldName = modelColumnUnbound.Id;

column.UnboundType = UnboundColumnType.Object;

column.OptionsColumn.AllowEdit = false;

column.ShowUnboundExpressionMenu = modelColumnUnbound.ShowUnboundExpressionMenu;

column.UnboundExpression = modelColumnUnbound.UnboundExpression;

}

}

IEnumerable<XafGridColumn> GetXafGridColumns() {

IEnumerable<XafGridColumn> xafGridColumns =

Model.Columns.OfType<IModelColumnUnbound>().Select(

unbound => Control.GridView.Columns[unbound.PropertyName] as XafGridColumn).Where(column => column != null);

return xafGridColumns;

}

public override void SynchronizeModel() {

var xafGridColumns = GetXafGridColumns();

foreach (var xafGridColumn in xafGridColumns) {

((IModelColumnUnbound) xafGridColumn.Model).UnboundExpression = xafGridColumn.UnboundExpression;

}

}

}

The above code uses the GetXafGridColumns method to return the grid columns that correspond to IModelColumnUnbound nodes. The web implementation is very similar and can be found here.

All that is left is to register our UnboundColumnSynchronizer like this,

public class UnboundColumnController : ViewController<ListView> {

protected override void OnActivated() {

base.OnActivated();

var gridListEditor = View.Editor as GridListEditor;

if (gridListEditor != null)

gridListEditor.CreateCustomModelSynchronizer += GridListEditorOnCreateCustomModelSynchronizer;

}

void GridListEditorOnCreateCustomModelSynchronizer(object sender, CreateCustomModelSynchronizerEventArgs createCustomModelSynchronizerEventArgs) {

createCustomModelSynchronizerEventArgs.ModelSynchronizer = new UnboundColumnSynchronizer((GridListEditor)sender, View.Model);

}

}

Note; Setting ShowUnboundExpressionMenu to true is only supported by Windows platform. There, an end user can modify the UnBoundExpression by invoking Grid’s expression editor

Together with the unbound column Xpand allows for up to 5 different approaches to creating calculated fields. In the next post we will discuss the pros and cons of each approach so stay tuned!


Δημοσίευση στην κατηγορία: , ,
XAF Workflow persistence storage
25 Αυγούστου 11 07:30 πμ | tolisss | 0 σχόλια   

The .NET Framework 4 ships with the SQL Workflow Instance Store which allows workflows to persist state information about workflow instances in a SQL Server 2005 or SQL Server 2008 database. However its implementation is based on stored procedures which can be a bit scary if you are not familiar with them. In addition our customers may follow different standards (Oracle, Firebird, VistaDB, MySQL, PostgreSQL etc.) and it’s unrealistic to hire more people to support SQL Server infrastructure.

Usually when dealing with these issues the first thing we do is to carry out a Google search for storage solutions. Surprisingly there is no such solution out there! Moreover there is very little useful code or samples available. Luckily XAF provides us with an easier route!

XAF is the perfect workflow modeling environment. It provides a ready made solution for creating and deploying a server that will execute workflows as described here.  In order to start modeling workflows we can use VS design time along with our re-hosted runtime Workflow designer and custom WF4 activities. XAF also gives us increased control over our workflows for example through the ability to manually start workflows. Finally since XAF uses XPO to access data we can easily support 16 different database systems simply by providing a connection string!

XPO Data Store Adapter XPO Data Store Adapter's Assembly Name Database Provider Assembly
AccessConnectionProvider DevExpress.Xpo.vXXX System.Data.dll
AdvantageConnectionProvider DevExpress.Xpo.vXXX.Providers Advantage.Data.Provider.dll 9.10.2.0
AsaConnectionProvider DevExpress.Xpo.vXXX.Providers iAnywhere.Data.SQLAnywhere.dll 11.0.0.12642
AseConnectionProvider DevExpress.Xpo.vXXX.Providers Sybase.Data.AseClient.dll 1.15.50.0
DB2ConnectionProvider DevExpress.Xpo.vXXX.Providers IBM.Data.DB2.dll 9.5.2.2
FirebirdConnectionProvider DevExpress.Xpo.vXXX.Providers FirebirdSql.Data.Firebird.dll 1.7.1.0
FirebirdSql.Data.FirebirdClient.dll 2.5.1.0
MSSqlConnectionProvider DevExpress.Xpo.vXXX System.Data.dll
MSSqlCEConnectionProvider DevExpress.Xpo.vXXX.Providers System.Data.SqlServerCe.dll 3.5.0
System.Data.SqlServerCe.dll 4.0.8482.1
MySqlConnectionProvider DevExpress.Xpo.vXXX.Providers MySql.Data.dll 5.2.5.0
OracleConnectionProvider DevExpress.Xpo.vXXX.Providers System.Data.OracleClient.dll 2.0.0.0
Oracle.DataAccess.dll 9.2.0.700
ODPConnectionProvider DevExpress.Xpo.vXXX.Providers Oracle.DataAccess.dll 10.1.0.200
PervasiveSqlConnectionProvider DevExpress.Xpo.vXXX.Providers Pervasive.Data.SqlClient.dll 2.10.0.15
PostgreSqlConnectionProvider DevExpress.Xpo.vXXX.Providers Npgsql.dll 2.0.11.0
SQLiteConnectionProvider DevExpress.Xpo.vXXX.Providers System.Data.SQLite.dll 1.0.61.0
VistaDBConnectionProvider DevExpress.Xpo.vXXX.Providers VistaDB.4.dll 4.0.0.0

More info @ Database Systems Supported by XPO

This is only one example of what XAF can do for us. XAF provides a comprehensive set of solutions that allow you to outsource all of the mundane programming tasks leaving you to focus purely on your business needs. For more info consult our docs, blogs, code central and support center.

Happy Workflowing!

Related Links
Blog posts
Online documentation

Videos


Δημοσίευση στην κατηγορία: , ,
Creating a State Machine module for eXpandFramework – Part 1
08 Αυγούστου 11 03:19 μμ | tolisss | 0 σχόλια   

Let me describe for a moment how we at DX work. We build and sell software which means that we only sell and provide support for products that have been built and tested by us! However I am here as a framework evangelist and huge XAF fan. This makes it my duty to spread the word as much as I can and make XAF even bigger. To this end through collaboration within the XAF community, we have been building and supporting eXpand. This framework follows XAF to the letter and takes things even further. eXpand gets its inspiration from real life situations and bases itself on examples from DX SUPPORT CENTER. eXpand is the first open source project based on the DevExpress eXpressApp Framework (XAF). More info is available at www.expandframework.com and our very existence relies on your efforts! Anyone is welcome to contribute and enjoy the rewards. It is not necessary to be a XAF guru, we can all manage to create a behavior taken from DevExpress code central. Let’s work together to enhance our beloved XAF!

Today we are going to deal with creating a reusable module for eXpandFramework. This new module will host State Machine logic therefore we are going to name it Xpand.ExpressApp.StateMachine. A Security logic similar to this is going to be the first resident however we are going to use permissions rather than manually writing the custom function criteria operator to the TargetObjectCriteria. This module can be used as a standalone without the need of eXpandFramwork for the moment. However keeping it under the eXpand umbrella will help us to share features/processes within the framework in the future.

First we need to create a new VS project that shares characteristics with the rest of the eXpand modules. Currently eXpand only provides a new Solution VS template. This means that we need to do things the old fashioned way, i.e. copying and pasting an existing module. Our behavior is platform independent thus it’s a good idea to choose a module that is also platform independent such as Xpand.ExpressApp.ViewVariants.

The next step is to open the cloned project, rename it and set its references to those shown in the pic below. It is important to leave all Xpand core references as they are.

image

It is advisable to register the original StateMachine module to avoid having to register it later.

image

XpandSystemModule is already registered since we used the Xpand.ExpressApp.ViewVarians project as a template.

We want (with the help of the existing XAF Security permissions system) to be able to assign special types of permissions to a role. We can then use these permissions to control the transition to certain states. The State Machine module uses XpoStateMachine and XpoState persistent classes. These classes can be linked to a permission by name. As a result a permission having 2 properties StateMachineName and StateName would be sufficient.

[NonPersistent]

public class StateMachineTransitionPermission : PermissionBase {

    public override IPermission Copy() {

        return new StateMachineTransitionPermission(Modifier, StateCaption, StateMachineName);

    }

 

    public StateMachineTransitionPermission() {

    }

    public override SecurityElement ToXml() {

        SecurityElement result = base.ToXml();

        result.AddAttribute("modifier", Modifier.ToString());

        result.AddAttribute("stateMachineName", StateMachineName);

        result.AddAttribute("stateCaption", StateCaption);

        return result;

    }

    public override void FromXml(SecurityElement e) {

        base.FromXml(e);

        Modifier =

            (StateMachineTransitionModifier)

            Enum.Parse(typeof(StateMachineTransitionModifier), e.Attributes["modifier"].ToString());

        StateCaption = e.Attributes["stateCaption"].ToString();

        StateMachineName = e.Attributes["stateMachineName"].ToString();

 

    }

    public StateMachineTransitionPermission(StateMachineTransitionModifier modifier, string stateCaption, string stateMachineName) {

        Modifier = modifier;

        StateCaption = stateCaption;

        StateMachineName = stateMachineName;

    }

    public override bool IsSubsetOf(IPermission target) {

        var isSubsetOf = base.IsSubsetOf(target);

        if (isSubsetOf) {

            var stateMachineTransitionPermission = ((StateMachineTransitionPermission)target);

            return stateMachineTransitionPermission.StateCaption == StateCaption &&

                   stateMachineTransitionPermission.StateMachineName == StateMachineName;

        }

        return false;

    }

 

    public StateMachineTransitionModifier Modifier { get; set; }

 

    public string StateMachineName { get; set; }

 

    public string StateCaption { get; set; }

}

 

A  Modifier property can be used to disable our permission, moreover the SecuritySystem is going to grant the permission by calling the IsSubsetOf method.

Finally, we are going to create a controller and check if a permission with the same state and statemachine name has been granted to our system. If not we are going to throw an

exception

 

public class StatePermissionController : ViewController, IModelExtender {

    void IModelExtender.ExtendModelInterfaces(ModelInterfaceExtenders extenders) {

        extenders.Add<IModelOptions, IModelOptionsStateMachine>();

    }

 

    protected override void OnActivated() {

        base.OnActivated();

        var stateMachineController = Frame.GetController<StateMachineController>();

        stateMachineController.TransitionExecuting += OnTransitionExecuting;

    }

 

    void OnTransitionExecuting(object sender, ExecuteTransitionEventArgs executeTransitionEventArgs) {

        var states = executeTransitionEventArgs.StateMachine.States.OfType<XpoState>();

        foreach (var state in states) {

            if (IsNotGranted(state))

                throw new UserFriendlyException("Permissions are not granted for transitioning to the " + state.Caption);

        }

    }

 

    bool IsNotGranted(XpoState state) {

        return IsNotGranted(new StateMachineTransitionPermission(StateMachineTransitionModifier.Deny, state.Caption, state.StateMachine.Name));

    }

 

    static bool IsNotGranted(IPermission permission) {

        var securityComplex = ((SecurityBase)SecuritySystem.Instance);

        bool isGrantedForNonExistentPermission = securityComplex.IsGrantedForNonExistentPermission;

        securityComplex.IsGrantedForNonExistentPermission = true;

        bool granted = SecuritySystem.IsGranted(permission);

        securityComplex.IsGrantedForNonExistentPermission = isGrantedForNonExistentPermission;

        return granted;

    }

}

During the writing of this post M. Brekhof asked if it is possible to hide the transition in the UI if there are no permissions. This is a certainly a useful feature to include in the new module. To implement it we can subscribe to the ItemsChanged event of the ChangeStateAction and use the IsGranted method there.

image

Using the model to control the above allows us more flexibility as we can choose whether to include these improvements or not. In order to do so we need to define and register a model extender.

image

It should be clear that this is a rapid development! In a few short minutes we have created a module which can be used as often as necessary to enhance the functionality of our applications. This is another fine example of getting the job done the XAF way!

So far we have not discussed how to create lookups for our StateMachineTransitionPermission StateMachineName,StateName properties. Don’t worry all of this will be featured in part 2. In the meantime if any of you need any other information please let me know so that I can cover it too.

Happy eXpanding!

eXpand is the first open source project based on the DevExpress eXpressApp Framework (XAF). More info is available at www.expandframework.com


Δημοσίευση στην κατηγορία: , ,
Manually starting workflows – the best choice
03 Αυγούστου 11 07:57 πμ | tolisss | 0 σχόλια   

Prerequisites
Manually starting workflows

In the first post of the series we saw how to start a workflow using a WCF service. Furthermore we also discussed doing this using the module’s out of the box mechanisms. So far however, we haven’t had time to analyze the reasons for choosing one method or the other. This post aims to clarify the situation.

WCF Solution

As Dennis likes to say, “There is no need to light a cigar with a nuclear reactor”. This is certainly true when it comes to the WCF solution as it can be somewhat unwieldy. In addition we have to come to terms with more technology as it requires configuration for even the smallest task. For example, the client always needs to know the WCF service address. It is also very difficult to work with WF instances because in order to accomplish common tasks (view, track status, generate reports, measure client service reply time) we need to introduce a system of persistent classes which will help to simulate the out of the box behavior. A third issue arises when modifying the solution because there is often a need for changes to occur in many places at the same time. For example when introducing additional properties we have to change client code and Receive contracts.

This option is only recommended when we have a large system (>10000 WF instances). Only then will we notice a gain in performance. This is because one WCF request can start a workflow which costs nothing compared to multiple Sql Queries. In all other cases we are fortunate that XAF allows us to take the easy road as usual!

Out of the box

Take our usual product ordering task; a client simply creates a new OrderRequest business object and fills the necessary members. A workflow with  an AutoStartWhenObjectIsCreated condition will start when the object is saved. After that we can access all the information in the workflow algorithm. This method allows us to,

Note that a similar process is described in Working with CRUD activities – Short Transactions

We would appreciate your feedback on this post. Has it been useful to you? Feel free to contact us  with any further questions

Related Links
Blog posts
Online documentation


Δημοσίευση στην κατηγορία: ,
How to use an eXpand module with an existing XAF application
01 Αυγούστου 11 12:25 μμ | tolisss | 0 σχόλια   

Let me describe for a moment how we at DX work. We build and sell software which means that we only sell and provide support for products that have been built and tested by us! However I am here as a framework evangelist and huge XAF fan. This makes it my duty to spread the word as much as I can and make XAF even bigger. To this end through collaboration within the XAF community, we have been building and supporting eXpand. This framework follows XAF to the letter and takes things even further. eXpand gets its inspiration from real life situations and bases itself on examples from DX SUPPORT CENTER. eXpand is the first open source project based on the DevExpress eXpressApp Framework (XAF). More info is available at www.expandframework.com and our very existence relies on your efforts! Anyone is welcome to contribute and enjoy the rewards. It is not necessary to be a XAF guru, we can all manage to create a behavior taken from DevExpress code central. Let’s work together to enhance our beloved XAF!

Using an eXpand module with an existing XAF application is an issue that is being raised a lot recently and I am sure it deserves a post and a place in Xpand Wiki. The following information applies to any Xpand module. Note that installing an Xpand module is almost as easy as using a XAF one.

Introduction

Firstly, as a base type for our application components it is imperative to use XpandWinApplication or XpandWebApplication. Therefore we need to reference Xpand.ExpressApp.Win or Xpand.ExpressApp.Web assemblies from our application projects and replace their components’ base types accordingly,

image

Additionally we need to reference Xpand.Persistent.BaseImpl. Having similar architecture with XAF, eXpand modules use interfaces and their implementations are hosted in the BaseImpl assembly. Xpand modules know how to locate the Business Objects they require so this is all we need to do at this point.

Note; it is possible to use a custom BaseImpl assembly.

Registering in Toolbox

Now, unless we are a XAF guru, we have to register the assemblies in the VS toolbox. I suggest creating the toolbox items within a new Xpand Tab as shown. At this point we don’t have the resources to create our own ToolBoxCreator utility. If any VS IDE guru wants to contribute such a tool, we owe him one!

image image

Registration

Registering and using a module is as easy as dragging and dropping it into the Application Designer. The designer will then add all required references and modules for us.

image

Give us your feedback

Was this post useful to you? Do you want to learn more about Xpand framework? We would love to hear your feedback!

Happy eXpanding!


Δημοσίευση στην κατηγορία: ,
Xaf Tip # 7 Dangerous Switch
24 Σεπτεμβρίου 09 03:09 πμ | tolisss | 0 σχόλια   
My good friend Martin Praxmarer while we are working on some cool feature for the new ModelDifference eXpand module pointed out the existence of an evil switch Suppose your team is responsible for creating a module with some kind of Permission so when the system is granted that permission a block of code will be executed, something like if (SecuritySystem.IsGranted( new MyPermission())){     //do something } and then you pass your module to another team or another consumer and he decides to use the “EVIL ONE” property that is exposed by DevExpress.ExpressApp.Security.SecurityBase class is name IsGrantedForNonExistentPermission and can be changed easily as shown in the next image What it does? As its name states inverse the behavior of the SecuritySystem.IsGranted

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , ,
How to zero your application startup time
21 Σεπτεμβρίου 09 11:10 μμ | tolisss | 0 σχόλια   
For this question don’t we all of us spend a lot of time ? But I think it is allowed to use a trick to spend our selves that time. Add to your model to attributes NotifyIcon, MinimizeOnClose. Since I am using Xaf I am going to present that with it but the code should be very similar to any other windows application so here are our attributes NotifyIcon: will add a tray icon for your app at the system tray with a context menu that will allow you to terminate your application and display it when you double click the icon public   partial   class NotifyIconController : WindowController {     public   const   string NotifyIconAttributeName = "NotifyIcon" ;     public NotifyIconController()    

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , ,
Xaf tip # 6 Linq your Session queries
17 Σεπτεμβρίου 09 04:07 μμ | tolisss | 0 σχόλια   
Pretty silent these days eh? I am working on a big refactoring on DictionaryDifference and have not much time to blog. But have another tip for my Xaf Tips series today maybe not strictly Xaf but is an XPO tip that you can use with your Xaf applications . The Problem Suppose your are a strongly typed fun like me or you want to use linq to query objects inside a transaction. In order linq to be used with XPO DevExpress provides XPQuery<T> class but unfortunately this do not support transactions. So the following test fails var work = new UnitOfWork(); new User(work){UserName = "Sam" }; User firstOrDefault = new XPQuery<User>(work).Where(user => user.UserName == "Sam" ).FirstOrDefault(); Assert.IsNotNull(firstOrDefault); The solution

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , ,
Xaf tip #5 Running Controllers everywhere
08 Σεπτεμβρίου 09 01:12 πμ | tolisss | 0 σχόλια   
I recently being asked a lot about a way of making Xaf front end (that is your Solution.Win,Solution.Web) able to host controllers. To many of them i answered that is not possible cause of the Xaf architecture but haven’t thought of it, It was a rushed answer. Anyway i do not have to make a lot of thoughts on it since my friend Panagiotis Kefalidis share that trick with us. First lets give an example of why you want to run controller in your front end. Many security systems need to have access to your executable and through it to your main form. For Xaf the only way to get access to your form is through a controller. So the trick is to fool Xaf front end to make it behave like a module. Modules are capable to run controllers. And how you can do that? It is really

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: ,
ModelArtifactState Xaf Power to the people
02 Σεπτεμβρίου 09 11:34 μμ | tolisss | 0 σχόλια   
Yesterday i was speaking with my friend John Pouliezos and he asked me how to the implement the following  scenario. John has managed to create a SharePoint feature and now he can have Xaf views as SharePoint lists. Cool eh? What he wanted is the following: for specific User roles to be able to filter a specific web listview by parsing the current browser url. Step1 : for specific User roles to be able to filter a specific web Aha sounds like ModelArtifactState’s job a lot. Cause that module is able to enable or disable behaviours /controllers (doing something) using permissions or the model. We are going to use permissions for this one So no code is needed for step1 ModelAsrtifactState module is going to help us. Step 2 : John explain to me the urls are

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , ,
eXpand 0.0.0.10 is out
01 Σεπτεμβρίου 09 06:21 πμ | tolisss | 0 σχόλια   
Latest version of eXpand is out and recompiled with Xaf 9.2.4 version New Module Additions AdditionalViewControlsProvider Validation ModelArtifactState WizardUI see ( Bend Xaf Applications with Model Artifact State Module ) Fixes enhancements via Google issues here Get latest version of expand here http://code.google.com/p/expandframework/ Technorati Tags: Xaf , eXpand , Release

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , ,
ModelArtifact AdditionalViewControlsProvider And MasterDetail videos republished
25 Αυγούστου 09 02:23 μμ | tolisss | 0 σχόλια   
Since I got many complaints about the low resolution of my videos I am on a search for a better video hosting service than YouTube. Robert suggested to use Silverlight service at Blogger Video embedding resolved but this one looks the same as YouToube. After spending some more time on researching on this I came across http://blip.tv/ excellent hosting service To get an idea how good they are I suggest you read their FAQs They accept almost all kinds of  Videos They are free They do not change the video after uploading The customization of the video playback controls is unlimited . You can configure almost anything on their well design interface I am going to use that excellent service to republish my videos So if you want to see those videos again in good

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , , , , ,
Xaf tip # 4
21 Αυγούστου 09 02:18 μμ | tolisss | 0 σχόλια   
This is my 4th post on my Xaf tips series Runtime Member creation on TypesInfo and XPDictionary When you are developing modules and need to generate runtime member you should be carefull which method you choose because the following is valid always Assert.IsNull(XafTypesInfo.Instance.FindTypeInfo( typeof (Country)).CreateMember( "TestMember" , typeof ( string ))); and this one not Assert.IsNull(XafTypesInfo.XpoTypeInfoSource.XPDictionary.GetClassInfo( typeof (Country)).CreateMember( "TestMember" , typeof ( string ))); So to test my sayings create a new Xaf Application add a controller and call public   override   void CustomizeTypesInfo(ITypesInfo typesInfo){     base .CustomizeTypesInfo(typesInfo);    

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , ,
Bend Xaf Applications with Model Artifact State Module
17 Αυγούστου 09 11:07 πμ | tolisss | 0 σχόλια   
How many times have you said “What a great pattern MVP is!!!” Look for example how is implement the hint engine of main Xaf demo. I will try to explain that implementation. Controllers There is a windowcontroller called AdditionalInfoController and from it 2 controllers derive WebShowAdditionalInfoController and WinShowAdditionalInfoController. What they do? they enable inserting any kind of control as the first control of a view. They are the engine, they implement a behaviour and they also serve as the Observer design pattern Observer pattern: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. I am going to refactor the code from the main demo and create 3 new modules

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , , ,
Implementing Master-Detail with No Code
13 Αυγούστου 09 11:31 μμ | tolisss | 0 σχόλια   
  eXpand already has this scenario enabled for windows forms applications. What you have to do is set 2 attributes and you are done!!! You have force your grid to display a child grid view eXpand is hosted at http://code.google.com/p/expandframework/ Technorati Tags: expand , DevExpress , Xaf

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , ,
Favor composition over inheritance
09 Αυγούστου 09 05:15 μμ | tolisss | 0 σχόλια   
There is a software design principle that states “ Favor composition over inheritance ” Inheritance is a cool way to change behavior. But we know that it's brittle, because the subclass can easily make assumptions about the context in which a method it overrides is getting called. There's a tight coupling between the base class and the subclass, because of the implicit context in which the subclass code I plug in will be called. Composition has a nicer property. The coupling is reduced by just having some smaller things you plug into something bigger, and the bigger object just calls the smaller object back. From an API point of view defining that a method can be overridden is a stronger commitment than defining that a method can be called. That Principe my friends

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , ,
Xaf tip #2
02 Αυγούστου 09 11:09 πμ | tolisss | 0 σχόλια   
Just come back from my short holidays this year and I am feeling very relaxed. So I though I should continue my Xaf tips series as I encounter them in my every day work. Be carefull of DevExpress.ExpressApp.DC.TypesInfo.FindTypeInfo method I am only going to say that each time you call the above method if the typeInfo that you expect to get back is not redistered on the system, a new one is going to be created and returned to you. so typesInfo.FindTypeInfo(typeof(Person))!=typesInfo.PersistentTypes.Where(info => info.Type==typeof(Person)).SingleOrDefault() and for you to imagine any kind of conflict you like take into account that a new table named Person is going to be created at your db with the following line if (typesInfo.FindTypeInfo(typeof(Person))!=null)

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , ,
eXpand 0.0.0.8 is out
24 Ιουλίου 09 02:12 μμ | tolisss | 0 σχόλια   
I am releasing a new version of expand this time using continuous integration provided by TeamCilty DictionaryDifferenceStore has now be able to work at all Security Scenarios (Complex or simple). There is one catch though if you want to use your own custom User or Role objects and you cannot modify any of the nested Role/User List view of the DictionaryDifference Views get latest version of expand here http://code.google.com/p/expandframework/

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , ,
Continuous integration for eXpand
24 Ιουλίου 09 02:08 μμ | tolisss | 0 σχόλια   
First of all thank you very much for your good words in eXpand . I am going to continue releasing modules and the next one will be a big one so please bear with me. But since I am relasing a lot of code and some other developers contact me that they want to contribute also. I think its time to to move on to apply a more continous integration to our build proccess. What I mean by that? the paragraph bellow was takes from martinfowler.com The easiest way for me to explain what CI is and how it works is to show a quick example of how it works with the development of a small feature. Let's assume I have to do something to a piece of software, it doesn't really matter what the task is, for the moment I'll assume it's small and can be done in a few hours. (We'll explore

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , , ,
Configurable low level datastore filtering provider module for Xaf
20 Ιουλίου 09 12:30 πμ | tolisss | 0 σχόλια   
This one is hard to explain so I would start with one scenario that can be implemented with ease. You have a request to create a windows form application that the data should be filtered according to the active skin, also the request says that Customers should be shared through skins. Another request for the same project is application data to be filtered according to the active user but customers to be shared across all users For such scenarios that are: Filter data at a low level so any logic above this level to still function (see validation rules) I have develop FilterDataStore module and I am going to release it as part of eXpand 0.0.0.7 To configure the module one have to add a filter provider at its application configuration file (see A practical guide

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , ,
DxCore plugins for Xaf are moving
19 Ιουλίου 09 11:36 μμ | tolisss | 0 σχόλια   
I am realizing a new version of eXpand (0.0.0.7) that will contain a configurable low level datastore filtering provider module and I am going to merge Coderush plugins into it as well. You have to download latest version of eXpand from http://code.google.com/p/expandframework/downloads/list and add only the following assemblies into your community folder if you are not interested in eXpand  DevExpress.ExpressApp.ModelEditor.v9.1 eXpand.Utils Wintellect.Threading eXpandAddIns

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , , , ,
Runtime distribution of model changes to a group of users
14 Ιουλίου 09 12:15 πμ | tolisss | 0 σχόλια   
I am going to demonstrate one more application scenario using eXpand and DictionaryDifferenceStore module. We are going to create to roles (hrempolyers , courierempoyers) and we are going to assign a difference Cutomer listview to each one of them Listview for HR people will see customers grouped by their birthday and listview for courier grouped by their address For both roles the navigation menu will contain the default User button that was provided by xaf . see how to setup DictionaryDifferenceStore module In the next video I have already created 2 extra Roles HRRole with Hr1, Hr2 Users CourRole with Cour1, Cour1 Users inside The above video was recorded with eXpand v0.0.0.6 http://code.google.com/p/expandframework/downloads/list Technorati Tags: eXpand ,

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , ,
Generate runtime members -- eXpand
10 Ιουλίου 09 02:12 μμ | tolisss | 0 σχόλια   
  Today I am going to saw you how easy is the Generation of runtime members. eXpand provides a controller that extends model schema and allow runtime generation of members without writing even 1 line of code ( Xaf power to the people!!!) For doing this You have to use a combination of features from eXpand.DictionaryDifference.dll && eXpand.ExpessApp.Win.dll This generation is doable due to the fact that we have use use DictionaryDifference module to store the model in the database, and since there is a clear distinguish between user model and application model, we can have use dictionarydifference UI to set the Model editor attribute that does that expansion, which is the IsRuntimeMember attribute defined at eXpand.ExpressApp.SystemModule.AddRuntimeFieldsFromModelToXPDictionary

Διαβάστε περισσότερα »

Δημοσίευση στην κατηγορία: , , , ,
Περισσότερες Δημοσιεύσεις Επόμενη »

Search

Go

Το Ιστολόγιο

Ιστορικό Δημοσιεύσεων

Συνδρομές