Saturday, December 29, 2012

ORM Magic–Importing from any datasource

This post will be on how to use the approach described in Fast prototyping requires an initial data import mechanism with Excel as input source. The technic is based on System.Data.DataSet class and can be applied to any type of input source!

Thanks to your reports and of course Slava’s help (XPO guru), XVideoRental importing mechanism has been improved a lot and now is faster, has notification events and is decoupled from XAF’s TypesInfo system. This makes it possible to simply copy the ImportData.cs file found in Common.Win project and use it in non XAF solutions!

In previous version this importing mechanism worked only when matching in types of input and output members. This means that if my output Oid property was a System.Guid then input should be of the same type. Now we have workaround this minor issue. If conversion is possible it will be done automatically without the need of any configuration or extra coding!

To better design, support, extend and describe the importing mechanism I used Mspec a functional testing framework and I open source the specifications in our community project eXpandFramework. These follow bellow,

MemberMapper, When Class Has a flag that includes all members
» should collect all members that belong to the class
» should not collect any base class member
» should create new members for each one of them

MemberMapper, When class does not have a flag that includes all ownmembers
» should not create members for those not marked with the attribute
» should create members and name them according to the attribute data
» should create a key property if not included in the conficuration

MemberMapper, When class attribute has data for base members
» should create and name them according to the attribute data
» should map their attributes

MemberMapper, When class is marked to include all member but member is marked seperately
» should use the member marking

MemberMapper, When mapping a referenced member
» should create a member with a dynamic type ownwer

MemberMapper, When reference type is not includedIN the configuration
» should create non reference member

ClassMapper, When creating dynamic classes
» should Create Classes only for the ones that have a marking attribute
» should name the classes taking data from marking attribute

ClassMapper, When class has many to many collection marked for importing
» should create intermediate classes
» should create an auto genareted key for this class
» should create 2 columns with names taken from the marked attribute

DictionaryMapper, When is mapping a dictionary
» should map all marked objects

InitDataImporter, When importing an object
» should create a new output object
» should assign all mapped properties

InitDataImporter, When input membertype is different than output
» should convert the value when simple type
» should convert the value when reference type


21 passed, 0 failed, 0 skipped, took 1.61 seconds (Machine.Specifications 0.5.2-98b543c).

The above specifications are evaluated with every eXpand build and you can see them in eXpand’s build server. Take a quick look at their code located in github to see how easy it is to write them (http://goo.gl/TNv4d).

Now lets see how to use our magic XPO ORM to import into the real world business domain like the one of our XVideoRental demo,

image

 

For the sake of complexity the input source will be a list of excel files and not just a simple Excel file with many sheets.

image

XPO supports a DataStore provider which is based on DataSet. So, first we fill a DataSet with the excel files and for this I will use some DataSet extension methods I contributed to eXpand (see http://goo.gl/TF26g)

static DataSet DataSet() {

    var dataSet = new DataSet();

 

    dataSet.ImportExcelXLS(new[]{

        "Customer", "Receipt", "Company", "CompanyType", "Country", "Employee", "Language", "Movie", "MovieArtist",

        "MovieArtistLine", "MovieCategory", "MovieCategoryPrice", "MovieCompany", "MovieItem",

        "MovieMovies_CountryCountries", "MoviePicture","Person","Artist","ArtistPicture","Rent"

    });

 

    return dataSet;

}

 

Now we are ready to create a UnitOfWork with this DataSet as DataStore like,

 

var inputUnitOfWork = new UnitOfWork(new SimpleDataLayer(new DataSetDataStore(DataSet(), AutoCreateOption.None)));

 

and finally call the Import method of the InitDataImporter class as shown bellow

 

var initDataImporter = new InitDataImporter();

            var unitOfWork = OutputUnitOfWork();

            var inputUnitOfWork = new UnitOfWork(new SimpleDataLayer(new DataSetDataStore(DataSet(), AutoCreateOption.None)));

            initDataImporter.Import(() => new UnitOfWork(unitOfWork.ObjectLayer), () => new UnitOfWork(inputUnitOfWork.ObjectLayer));

This simple, however powerful technic can be applied to any type of input source as long as you are able to fill a DataSet!

You can download a sample project was created with v12.2.5 of our Suite from Importer.Console.

Happy New Year to everybody!

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Wednesday, December 19, 2012

XVideoRental real world application (RWA) – The overview

XAF knowledge base is really rich and in our Support Center you can find solutions for all common business problems. Moreover our community project www.expandframework.com has tones of reusable solutions, we collected a few of them and applied them to the video rent business. The demo is available with 12.2.4 version of our Suite and can be found in the same folder with the other amazing XAF demos!

XAF is a framework that provides the tools that a developer needs for building business solutions.

  1. A state of the art multi layered configuration system – The Application Model.
  2. A robust and flexible Security System that can be used to protect our data and control the auto generation of the UI based on Role permissions
  3. Its own reflection system (TypesInfo)– with amazingly simple ways to do what .NET does not offer eg. Runtime members, dynamic attributes etc.
  4. A well designed architecture to guide you where you should put your code. Moreover a very flexible modularization for structuring and further supporting any solution.
  5. WinForms/ASP.NET integration for a large number of our components
  6. Rich documentation and a click and run SDK!

XVideoRental is a real world application (RWA). It is designed as a clone of our WinForms VideoRent application and demos only a small part of XAF capabilities. XAF provides the tools/architecture to do extraordinary things so we have followed a (no code)/(design at runtime) approach!. We recommend you to open the legacy Winforms demo and XVideoRental side by side and compare how much faster and richer is XAF development versus the traditional one. Moreover take a look at this help document that extensively compares traditional vs XAF development.

  1. XVideoRental uses a mechanism to serialize classes into Application Model and control them further from there! Therefore minimizes the learning curve since it is based on your existing component knowledge. (see this blog)
  2. It is a modeling rather than development technic. In addition allows further modeling at runtime since XAF already provides a runtime model editor.
  3. Implementations are collected from our usual places (Support Center / Code Central) / www.expandframework.com.

The XVideoRental demo has three projects:

Common.Win

This is a library (not XAF module) and contains 95% of the code needed to model the VideoRental business! As a library can be reused from all domains and not only for video rental business. By extending the model as discussed in Dressing up our classes – Date with a model tonight! it is possible to create an abstract mechanism and control any class/component from there. Since all business operations can be modeled, the library contains controllers like NetIncomeController, TopObjectController that map to the real world meanings and can be applied to any domain. The XAF Application Model serves as an abstraction from technology and business specifics. This module is assembled by collecting the classes/implementations from our Support Center and from our community project www.expandframework.com.

XVideoRental.Module.Win

References Common.Win library and simple initializes the required classes/controllers by deriving from the abstract implementation of Common.Win library. However even if it is possible to “model” any behavior sometimes technical depth must be considered. Therefore in the project you will find a small number of video rental specific classes. In this project you can also find the model differences for this business domain.

XVideoRental.Win

This is the application project and contains no code. Only a few default configurations like module and security registrations.

In the next post we are going to discuss the steps involved in building this application. I remind you again that all code functionality is borrowed from our community, this means that code / ideas really belong to you! We welcome more of your contributions and ideas to build even more wonderful applications. Please explore this demo and we are waiting for your feedback in order to blog more about features that interest you.

A similar version can found in our community project www.expandframework.com. This version has exactly the same functionality as the original demo. However it references directly the eXpand framework so the Common.Win project does not exist nor the initialization of the controllers in the XVideoRental.Module.Win.

We are looking forward for your feedback and contributions in order to make this demo even more powerful! In its current state, a developer can replace before lunch all the business objects with objects of a different business domain then package the application and go to customer and continue development there, at runtime! The final goal as developers is to build such configurable applications that business users can use and modify and shift this weight of our backs. XAF provides all the tools for this and this demo is a proof for this!

Bellow is a short video that shows this demo. You can find about two more dozen of images of this demo in our FB group

PS: A thanks to everybody that already provided feedback and reported issues with this demo. We already provided a newer version with improved performance and you can find it here. For posts related to the XVideoRental demo please subscribe to to the XVideoRental tag

Happy XAFing!

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, December 3, 2012

Dressing up our classes – Date with a model tonight!

Classes are in a sense behavior libraries. To initialize or configure them, we can use their properties. Serialization is a technic that helps distribute the state of our classes. In this post we will discuss how to serialize any class in the multi-layer XAF model! Then we finish with the model synchronizers which will control the class. Having a class or a part of a class serialized in the model makes it possible to continue development there without writing more code (declarative/runtime approach).

Runtime classes

In .NET is super easy to create runtime classes or interfaces. The following snippet will create a assembly with a Dynamic class.

var provider = CodeDomProvider.CreateProvider("c#");

var results = provider.CompileAssemblyFromSource(new CompilerParameters(), new[] { @"public class DynamicClass{}"        });

Assembly compiledAssembly = results.CompiledAssembly;

Modeling

XAF’s super advanced and simple model technology is using interfaces for design and further extension. This is well documented How to: Extend Application Model. To serialize any class on the XAF model we simply need to use reflection, extract an interface from the class and extend any part of the model we want with it.

Let’s see a few examples using XAF build-in components.

1) GridListEditor

XAF’s GridListEditor is based on the GridView class which is a very sophisticated component with a lot of properties. Serializing it into the model allow us to control it from there. Using the model it is possible to work at runtime and since we have a lot of properties it is wise to serialize their help as well (see red arrow).

image

2) ChartListEditor

This is a very useful editor that also needs better control from our model. Note that this model serialization is reusable from all our projects!

image

This technic can boost our runtime experience and make it possible to work side by side with our customer building really fast. Furthermore it is applicable to any class or component. Let’s a few more interesting examples.

3) Repository Items

XAF’s DX PropertyEditors render DX controls which store their configuration in RepositoryItem classes. We can serialize all ReporitoryItem descendants and extend the IModelColumn. As a result by simply changing a model attribute we can do things at runtime that with a code approach would be very time consuming.

image

4) The SchedulerListEditor

image

5) The PivotListEditor

This one uses the same serialization approach however since this is a very useful editor we modeled a few extra behaviors – the pivot rules!. We would probably create a separate post about them.

image

Furthermore here we need to notice that we can model business meanings such as NetIncome, so for the following model modifications,

image

XAF will render the View bellow without any coding or dependency to any object!

image

Another example, when we talk about the TopObject meaning, we can model it like

image

and XAF will give us the following View again without writing not even one line of code (no code==no bugs)

image

Model synchronization

ModelSynchronizers can be used to:

a) set up an entity according to the configuration stored in the Application Model
b) Persists the configuration of an entity into the Application Model

Model’s nature makes it very abstract so since the attributes of the model are automatically generated from the properties of a class, its rather easy to do the opposite. Therefore we can write an abstract class that will implement IModelSynchronizable interface. The method SynchronizeValues is reading from any class and updates the model. The method ApplyValues is reading the values of the model and synchronize any class that properties match model’s attribute Ids.

protected void SynchronizeValues(ModelNode modelNode, object component, PropertyDescriptorCollection properties) {

    foreach (var valueInfo in GetModelValueInfos(modelNode)) {

        var propertyDescriptor = properties.Find(valueInfo.Name, false);

        if (propertyDescriptor != null) {

            var propertyValue = GetPropertyValue(component, propertyDescriptor, valueInfo, modelNode);

            var modelValue = GetSynchronizeValuesNodeValue(modelNode, valueInfo, propertyDescriptor, valueInfo.PropertyType.IsNullableType(), component);

            if (modelValue != null && !modelValue.Equals(propertyValue)) {

                modelNode.SetValue(valueInfo.Name, propertyValue);

            }

        }

    }

}

 

protected void ApplyValues(ModelNode node, object component, PropertyDescriptorCollection properties) {

    foreach (var valueInfo in GetModelValueInfos(node)) {

        var propertyDescriptor = properties.Find(valueInfo.Name, false);

        if (propertyDescriptor != null) {

            var nodeValue = GetApplyModelNodeValue(node, valueInfo);

            if (nodeValue != null) {

                var propertyType = propertyDescriptor.PropertyType;

                var propertyValue = propertyDescriptor.GetValue(component);

                if ((!IsDefaultCoreValue(nodeValue, propertyType) || (!nodeValue.Equals(propertyValue))) && propertyType.IsValidEnum(nodeValue)) {

                    if (!nodeValue.Equals(propertyValue))

                        propertyDescriptor.SetValue(component, nodeValue);

                }

            }

        }

    }

}

 

Finally for each component we want to synchronize we create a descendant of the above implementation. For example,

AdvBandedListEditor

public class AdvBandedViewOptionsSynchronizer : ComponentSynchronizer<DevExpress.XtraGrid.Views.BandedGrid.AdvBandedGridView, IModelOptionsAdvBandedView> {

    public AdvBandedViewOptionsSynchronizer(AdvBandedListEditor control)

        : base(control.GridView, control.Model.OptionsAdvBandedView, ((IColumnViewEditor)control).OverrideViewDesignMode) {

    }

}

 

ChartControlListEditor

public class ChartControlSynchronizer : ComponentSynchronizer<DevExpress.XtraCharts.ChartControl, IModelOptionsChart> {

    readonly XafApplication _application;

 

We have discussed ways to model components into a distributable layer that describes a XAF. Even more we show how simple would be a model representation of business meanings (eg. NetIncome). It is clear that these tools are reusable from any project. We only need to feed XAF with a business domain and a few model modifications even in runtime to be able to have a working solution! A solution so rich in features that it is impossible to implement using the traditional approach.

The code and screen shots are taken from the XVideoRental application. This demo that can be found along with the other XAF demos in v12.2. Next posts will be about this new demo that really proves how XAF can save our time by lifting the development to the runtime!

P.S. If you are a facebook fun you can support us with a like for our new XAF page.

We are happy to read your feedback about this!. Remember that your questions are the best candidates for future posts.

Happy XAFing!

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Thursday, November 8, 2012

Let’s create metadata based permission policies

XAF has a great security system which can be used to protect our data either at client or server side. There is also great support for modifying the Security behavior at runtime using a permission matrix. However we need to provide initial before distributing our application. In this post we are going to discuss a way connecting methods that describe permission policies with our domain objects using metadata (Attributes).

For supplying initial data XAF provides a well documented approach through ModuleUpdaters. We can use them and write methods that create initial permissions. There are also many extension methods that can help us write faster code,

image

Full permission policy

This policy can be applied to any role and give full permission for the related objects. To connect a domain object with a method we need to do the following:

  1. Define a FullPermissionAttribute as,

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]

    public class FullPermissionAttribute : Attribute {

    }

     

  2. Decorate all related objects

    [FullPermission]

    public class MovieArtist : VideoRentalBaseObject {

    [FullPermission]

    public class Artist : VideoPerson {

  3. With the use of XAF’s sub types info metadata API write an abstract algorithm that will enumerate all domain objects and assign full permission to them for a certain role

    public static void CreateFullPermissionAttributes(this SecuritySystemRole systemRole,  bool defaultAllowValues = true) {

        var persistentTypes = XafTypesInfo.Instance.PersistentTypes.Where(info => info.FindAttribute<FullPermissionAttribute>() != null);

        foreach (var typeInfo in persistentTypes) {

            systemRole.CreateTypePermission(typeInfo.Type,  defaultAllowValues);

        }

    }

    public static SecuritySystemTypePermissionObject CreateTypePermission(this SecuritySystemRole systemRole, Type targetType, bool defaultAllowValues = true) {

        var permission = systemRole.CreateTypePermission(targetType);

        permission.TargetType = targetType;

        permission.AllowDelete = defaultAllowValues;

        permission.AllowNavigate = defaultAllowValues;

        permission.AllowRead = defaultAllowValues;

        permission.AllowWrite = defaultAllowValues;

        permission.AllowCreate = defaultAllowValues;

        return permission;

    }

  4. Invoke the CreateFullPermissionAttributes form the roles you want to apply inside the ModuleUpdater’s

    public override void UpdateDatabaseAfterUpdateSchema() {

        base.UpdateDatabaseAfterUpdateSchema();

        var employersRole = ObjectSpace.GetRole<SecuritySystemRole>("Employers");

        employersRole.CreateFullPermissionAttributes();

Permission Behavior policy

A common policy for an application is a “settings” policy. Which really means that for certain roles like the employee role there should be limited access to objects that store “settings” data. To implement this we can follow the follow steps

  1. Define an attribute to decorate our objects as in previous step. This time we do not know the policy name (settings) so we design this as an Enum parameter in the ctor.

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]

    public class PermissionBehaviorAttribute : Attribute {

        readonly string _name;

     

        public PermissionBehaviorAttribute(object @enum) {

            if (!@enum.GetType().IsEnum)

                throw new NotImplementedException();

            _name = Enum.GetName(@enum.GetType(), @enum);

        }

     

        public PermissionBehaviorAttribute(string name) {

            _name = name;

        }

     

        public string Name {

            get { return _name; }

        }

    }

     

  2. Design an enumeration to hold all possible security policies

    public enum PermissionBehavior {

        Admin,

        Settings,

        ReadOnlyAccess

    }

     

  3. Decorate related objects

    [PermissionBehavior(PermissionBehavior.ReadOnlyAccess)]

    public class Language : VideoRentalBaseObject {

  4. Create a method to describe the ReadOnlyAccess permission policy inside ModuleUpdater.

    public class Updater : ModuleUpdater {

        void ReadOnlyAccesPermissionBehaviour(SecuritySystemRole securitySystemRole, ITypeInfo typeInfo) {

            securitySystemRole.SetTypePermissions(typeInfo.Type, SecurityOperations.ReadOnlyAccess, SecuritySystemModifier.Allow);

        }

  5. With the use of XAF’s sub types info API write an abstract algorithm that will enumerate all domain objects and invoke a delegate with same parameters as the method in step 4

    public static void CreatePermissionBehaviour(this SecuritySystemRole systemRole, Enum behaviourEnum, Action<SecuritySystemRole, ITypeInfo> action) {

        var typeInfos = XafTypesInfo.Instance.PersistentTypes.Where(info => {

            var permissionBehaviorAttribute = info.FindAttribute<PermissionBehaviorAttribute>();

            return permissionBehaviorAttribute != null && permissionBehaviorAttribute.Name.Equals(Enum.GetName(behaviourEnum.GetType(), behaviourEnum));

        });

        foreach (var typeInfo in typeInfos) {

            action.Invoke(systemRole, typeInfo);

        }

    }

     

  6. Invoke the CreatePermissionBehaviour inside the ModulerUpdater feeding it with the ReadOnlyAccesPermissionBehaviour method of step 4

    employersRole.CreatePermissionBehaviour(PermissionBehavior.ReadOnlyAccess, ReadOnlyAccesPermissionBehaviour);

In this post we created reusable algorithms from any XAF projects to help us speeding up the configuration of the initial permissions. When of course talking about code reusability we talk about money saving!

P.S. In a real world application the above coding will be converted to a permission matrix UI representation like,
image

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

Next post will be about what else? its model time!

Happy XAFing as always.

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Wednesday, November 7, 2012

Visiting dashboards

DashboardView is a type of XAF View that is used to display several Views side-by-side. However XAF by default does not provide any connection between these Views. In this post, with the help of XAF model, we will discuss a few abstract connection mechanisms and possible uses of dashboards.

Cascading ListViews

In a dashboard, in order to connect the ListViews we need first to connect their models. This can be done using the following interfaces,

public interface IModelDashboardViewFilter : IModelNode {

 

    [DataSourceProperty("FilteredColumns")]

    IModelColumn FilteredColumn { get; set; }

 

    [DataSourceProperty("DataSourceViews")]

    IModelListView DataSourceView { get; set; }

}

[ModelAbstractClass]

public interface IModelDashboardViewItemEx : IModelDashboardViewItem {

    IModelDashboardViewFilter Filter { get; }

} 

and then extend XAF’s model, see also our documentation on extending the model

public void ExtendModelInterfaces(ModelInterfaceExtenders extenders) {

    extenders.Add<IModelDashboardViewItem, IModelDashboardViewItemEx>();

}

This design allows us to use Model Editor to connect our views. In the following image we see that the selected objects of the Customer_ListView_Calendar are going to filter the Calendar list view on the Receipt.Customer field.

image

Next we see this dashboard view in action, a SchedulerListEditor on the right is filtered by a GridListEditor,

image

Following we see this technic applied to 3 ListViews. The selected pie section of the left View filters the pivot which in its turn filters a LayoutListEditor!

image

Cascading views are as well useful for filtering reports, so by selecting objects on the left View we create a report on the right view and everything is inside a Tabbed MDI environment!

image

Of course we haven’ wrote the code yet but this is the easy part. XAF’s API is so rich and so well designed that is like we speak our native language! The great thing when XAFing is that our code is fully reusable from any project since it has no knowledge of our domain objects.

Let try to form our requirement in English first:
For each ListView in a Dashboard we need to filter another View when the selection is changed

And now in XAF language Smile:

protected override void OnViewControlsCreated() {

    base.OnViewControlsCreated();

    foreach (var result in View.Items.OfType<DashboardViewItem>()) {

        var frame1 = result.Frame;

        if (frame1 != null && frame1.View is ListView) {

            var listView = ((ListView)frame1.View);

            DashboardViewItem result1 = result;

            listView.SelectionChanged += (sender, args) => OnSelectionChanged(new SelectionChangedArgs(listView, result1));

        }

    }

void OnSelectionChanged(SelectionChangedArgs selectionChangedArgs) {

    var dataSourceListView = DataSourceListView((IModelListView)selectionChangedArgs.DashboardViewItemModel.View);

    if (dataSourceListView != null) {

        var dashboardViewItems = View.Items.OfType<DashboardViewItem>();

        foreach (var dashboardViewItem in dashboardViewItems) {

            var modelDashboardViewItemEx = (IModelDashboardViewItemEx)dashboardViewItem.GetModel(View);

            FilteredListView(dataSourceListView, dashboardViewItem, modelDashboardViewItemEx);

        }

    }

Controlling DashboardViewItem visibility

Cascading views are really powerful and soon we will have the need to hide an intermediate view in the chain but being able to filter other views upon it. Therefore we need to add a Visibility property in our model and handle it from our code.

public interface IModelDashboardViewItemEx : IModelDashboardViewItem {

    [DefaultValue(ViewItemVisibility.Show)]

    ViewItemVisibility Visibility { get; set; }

and in a reusable from all projects controller implement the required logic.

protected override void OnActivated() {

    base.OnActivated();

    ((ISupportAppearanceCustomization)View.LayoutManager).CustomizeAppearance += LayoutManagerOnCustomizeAppearance;

 

}

void LayoutManagerOnCustomizeAppearance(object sender, CustomizeAppearanceEventArgs customizeAppearanceEventArgs) {

    var modelDashboardViewItem = View.Model.Items.OfType<IModelDashboardViewItemEx>().FirstOrDefault(item => item.Id == customizeAppearanceEventArgs.Name);

    if (modelDashboardViewItem != null)

        ((IAppearanceVisibility)customizeAppearanceEventArgs.Item).Visibility = modelDashboardViewItem.Visibility;

}

Displaying HTML Messages

A DashboardView does not have direct dependency with our domain objects. Therefore we can easily use it, even at runtime, to display static text view items and other controls (ControlDetailItem) or images (StaticImage).

image

XAF has great support for HTML Formatting so a Static Text like “<u><b>Hello</b></u>” will render the following:

image

Simulating View inheritance

XAF does not support View inheritance however we can extend our model and support it. Lets take the case that we have a very complex listview and we want to display it in both in MasterDetail and ListViewOnly modes without the need to support two View versions. For this we have to extend again the model, this time by a MasterDetailMode property and implement the logic in a ViewController.

[ModelAbstractClass]

public interface IModelDashboardViewItemEx : IModelDashboardViewItem {

    MasterDetailMode? MasterDetailMode { get; set; }

public class DashboardInteractionController : ViewController<DashboardView>, IModelExtender {

    protected override void OnViewControlsCreated() {

        base.OnViewControlsCreated();

        ResetMasterDetailModes();

    }

    void ResetMasterDetailModes() {

        foreach (var masterDetailMode in _masterDetailModes) {

            masterDetailMode.Key.MasterDetailMode = masterDetailMode.Value;

        }

        _masterDetailModes.Clear();

    }

 

    protected override void OnActivated() {

        base.OnActivated();

        foreach (var item in View.GetItems<DashboardViewItem>().Select(item => item.GetModel(View)).OfType<IModelDashboardViewItemEx>()) {

            AssignMasterDetailModes(item);

        }

    }

 

    void AssignMasterDetailModes(IModelDashboardViewItemEx modelDashboardViewItem) {

        if (modelDashboardViewItem.MasterDetailMode.HasValue) {

            var modelListView = modelDashboardViewItem.View as IModelListView;

            if (modelListView != null) {

                _masterDetailModes.Add(modelListView, modelListView.MasterDetailMode);

                modelListView.MasterDetailMode = modelDashboardViewItem.MasterDetailMode.Value;

            }

        }

    }

Since XAF has a great modularization system the core classes/implementations of the above ideas are included in this zip file. However we will not update the contents of the zip file. For locating up to date versions each file in the zip has an OnlineRepoLocation attribute that points to eXpandFramework’s Github repository.

This post adds a few more tools in our development library that can leverage the XAF power using the Model. When we “model” there are three basic advantages:

  1. We can use these model tools at runtime. For this XAF already provides a runtime time Model Editor.
  2. We create robust unbreakable code and since we model instead of developing we mostly have no bugs only wrong configuration!
  3. Implementations are reusable from all our projects!

Next post we will boost our R&D times even further and discuss a bit about Security system policies.

P.S.: We are preparing detailed samples demonstrating all the above ideas Smile, stay tuned!

If some of you have invented similar ways to connect your dashboards. You can use our support center and share them with the rest of the community.

Happy XAFing!

Subscribe to XAF feed
Subscribe to community feed

DiggIt!