eXpress App Framework Team

February 2013 - Posts

  • XAF Core Improvements – Using Entity Framework and XPO Data Models in One Application (Coming in 12.2.7)

    The XAF team is constantly working to improve Entity Framework (EF) support for XAF. In the previous minor update (12.2.6), we extended the number of extra EF-compatible modules to include the Chart, Pivot Grid and Tree List modules, so the most popular modules are now compatible. In the upcoming 12.2.7 update, we introduce the capability to use both the Entity Framework and XPO business models in a single application. For instance, with this feature you can reuse the EF model from a non-XAF application in your existing XPO-based XAF project. As a result, your application will access two databases, the first one via XPO and the second via EF. Let’s take a look at an example.

    Add an EF Data Model in Code

    In the module project, reference the System.Data.Entity.dll, EntityFramework.dll and DevExpress.ExpressApp.EF.v12.2.dll assemblies and implement the following EntityFrameworkSampleObject and MyDbContext classes.

    using System.ComponentModel;

    using System.Data.Entity;
    using DevExpress.Persistent.Base;
    using DevExpress.ExpressApp.DC;
    // ...
    [DefaultClassOptions]
    public class EntityFrameworkSampleObject {
    [Browsable(false)]
    public int Id { get; protected set; }
    public string Name { get; set; }
    [FieldSize(FieldSizeAttribute.Unlimited)]
    public String Description { get; set; }
    }

    public class MyDbContext : DbContext {
    public MyDbContext(string connectionString) : base(connectionString) { }
    public DbSet<EntityFrameworkSampleObject> SampleObjects { get; set; }
    }

    To enable the automatic collection of EF Code First entities, add the following code to the module's constructor located in the Module.cs file.

    using DevExpress.ExpressApp.EF;
    // ...
    public MySolutionModule() {
    // ...
    ExportedTypeHelpers.AddExportedTypeHelper(new EFExportedTypeHelperCF());
    }

    Add an XPO Data Model in Code

    In the module project, implement the following BaseObject descendant.

    using DevExpress.Xpo;
    using DevExpress.Persistent.Base;
    using DevExpress.Persistent.BaseImpl;
    using DevExpress.ExpressApp.DC;
    // ...
    [DefaultClassOptions]
    public class XpoSampleObject : BaseObject {
    public XpoSampleObject(Session session) : base(session) { }
    private string name;
    public string Name {
    get { return name; }
    set { SetPropertyValue("Name", ref name, value); }
    }
    private string description;
    [Size(SizeAttribute.Unlimited)]
    public String Description {
    get {return description; }
    set { SetPropertyValue("Description", ref description, value); }
    }
    }

    Populate the DefaultObjectSpaceProviders Collection

    By default, the CreateDefaultObjectSpaceProvider method implemented in the WinApplication.cs and WebApplication.cs files assigns an XPObjectSpaceProvider instance to the ObjectSpaceProvider parameter. Instead, you can add multiple Object Space Providers to the ObjectSpaceProviders parameter. XAF will automatically determine what Object Space Provider should be used to create an Object Space for each particular business object type. Modify the default implementation of the CreateDefaultObjectSpaceProvider method for both Windows Forms and ASP.NET application projects in the following manner.

    using DevExpress.ExpressApp.DC;
    using DevExpress.ExpressApp.EF;
    // ...
    protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args) {
    args.ObjectSpaceProviders.Add(new XPObjectSpaceProvider(
    ConfigurationManager.ConnectionStrings["ConnectionStringXpo"].ConnectionString, null));
    args.ObjectSpaceProviders.Add(new EFObjectSpaceProviderCF(
    typeof(MyDbContext), (TypesInfo)TypesInfo, null,
    ConfigurationManager.ConnectionStrings["ConnectionStringEF"].ConnectionString));
    }


    Specify Connection Strings for EF and XPO

    The code in the previous section reads connection strings for each Object Space Provider from the configuration file (App.config in a Windows Forms application project and Web.config – in an  ASP.NET application project), so specify the ConnectionStringXpo and ConnectionStringEF connection strings in both files.

    <connectionStrings>
    <add name="ConnectionStringXpo"
    connectionString="Integrated Security=SSPI;Pooling=false;Data Source=(local);Initial Catalog=MultipleORMsExampleXpo" />
    <add name="ConnectionStringEF"
    connectionString="Integrated Security=SSPI;Pooling=false;Data Source=(local);Initial Catalog=MultipleORMsExampleEF" />
    </connectionStrings>


    Run the Application

    You can now run the Windows Forms or ASP.NET application to see that both EF and XPO objects are accessible.

    EF XPO_Office2013

     

    The EntityFrameworkSampleObject objects persist on the MultipleORMsExampleEF database, and XpoSampleObject objects persist on the MultipleORMsExampleXpo database.

    EF XPO_DB

    This small feature is helpful when you have a task similar to the one described in Q433494.

  • Dashboards in the real world – A Scotland strike!

    Updated 10/06/13
    Dashboard web integration module

    The DevExpress Universal Subscription now includes an interactive data visualization Dashboard for the Windows, Web and Mobile devices. The DevExpress Dashboard delivers solutions that allow any enterprise to visually explore business trends using stunning and easily understood performance indicators.

    If you are an XAF user, you already know that a framework such as XAF provides reusable building blocks to quickly build feature-rich business applications for Windows and the Web. In this post, I’ll discuss how Stephen Manderson, an XAF user from Scotland merged the capabilities of XAF and DevExpress Dashboard to create a new reusable XAF Dashboard module.

    To demonstrate this Dashboard integration, we’ll use our XVideoRental RWA demo. The sample is available for your review at the bottom of this post. 

    XAF users already know that dashboard support is part of the shipped product.  A few days ago, I posted a Visiting Dashboards blog where I discussed possible native implementation, user case scenarios and extensions in order to deliver dashboard solutions that address real problems without writing any code!

    Stephen Manderson was recently asked by a customer if it was possible for end users to create dashboards without going through IT to request changes and modifications to their system. The solution as you can imagine was the migration of the Dashboard Suite to his XAF application.

    Stephen’s goals were simple.

    1. Create dashboards like any other BO at runtime.
    2. Pass any number of Target Persistent Object as data sources.
    3. Restrict access to dashboards based on Roles.

    The DashboardDesigner

     

    This step is rather simple, we only need to drag this DashboardDesigner component into an empty windows form:

     

    image

     

    Displaying custom forms in XAF requires no special skills and is well documented: How do I show a custom window?

     

    Create dashboards like any other BO at runtime

    Working with XAF is pretty straight forward. Let’s begin with a DX component (DashboardDesigner) that we wish to integrate. Almost all our components are serializable and the DashboardDesigner is no exception. This means that we need a Persistent object to host the Xml for the layout and a collection of XAF BO Types to be assigned as data sources.

    To start we can use the following interface:

    public interface IDashboardDefinition {

        int Index { get; set; }

        string Name { get; set; }

        Image Icon { get; set; }

        bool Active { get; set; }

        string Xml { get; set; }

        IList<ITypeWrapper> DashboardTypes { get; }

    }

    For the sake of simplicity I wont post the full implementation however you can grab it and follow its history in eXpand’s github repo or in the sample at the end of this post.

     

    The Xml property along with the Designer’s LoadFromXml method can be used to load the Designer’s layout. So we need:

    1. To create a SimpleAction in a ViewController. We chose a ViewController instead of any other Controller simply because we are targeting a specific view and not the whole app.
    2. Then we configure the controller a bit further, to activate it only for the BO that implements the IDashboardDefinition.
    3. Finally we subscribe to the SimpleAction’s Execute event, and we load the Windows form with the Dashboard designer component.

    public class DashboardDesignerController : ViewController {

        readonly SimpleAction _dashboardEdit;

     

        public DashboardDesignerController() {

            _dashboardEdit = new SimpleAction(this, "DashboardEdit", PredefinedCategory.Edit);

            TargetObjectType = typeof(IDashboardDefinition);

            _dashboardEdit.Execute += dashboardEdit_Execute;

        }

     

        public SimpleAction DashboardEditAction {

            get { return _dashboardEdit; }

        }

     

        void dashboardEdit_Execute(object sender, SimpleActionExecuteEventArgs e) {

            using (var form = new DashboardDesignerForm()) {

                new XPObjectSpaceAwareControlInitializer(form, Application);

                form.LoadTemplate(View.CurrentObject as IDashboardDefinition);

                form.ShowDialog();

            }

        }

     

    In snippet above we chose to implement the LoadTemplate method in the DashboardDesignerForm because the Dashboard’s XML loading is not of XAF concern. This form is another separate windows based layer.

    Visualizing our business data in the designer

    The dashboard designer allows us to see our XAF data and shape our dashboards in real time as shown:

     

    image

     

    This designer is similar to our Reports designer but does not offer support for dynamic members aliases, which we covered in depth in the Dynamic member aliases from Application Model blog.

     

    Dashboards in action

     

    To visualize our dashboards we have to:

    1. Dynamically populate the navigation menu items

      We wish to extend XAF’s functionality, we must locate the responsible built-in controller, which leads us to the ShowNavigationItemController where we can subscribe to its events and populate the navigation items from the DashboardDefinition persistent objects. A possible implementation can be found in WinDashboardNavigationController.cs or you can follow its history online.

    2. Modify XAF’s security system to restrict access to dashboards based on Roles.

      Since we truly care about making it easy for the business user, the sample is using the implementation discussed in depth in the User friendly way to add permissions blog.

    3. Display the dashboard using the built-in DashboardViewer control.

      Here we easily can follow an SDK sample: How to show custom forms and controls in XAF (Example). In short, we need to create and return a new DashboardViewer control by overriding the CreateControlCore method of a PropertyEditor. In case we want to access extra system info we may use a different class (and not the PropertyEditor discussed in Implement Custom Property Editors). 

    Our active dashboards are linked in the “Dashboards” navigation group; this can be renamed and reordered so all changes are reflected within this group. The end result in the post’s sample looks like the following:

     

    image

     

    image

     

    image

    What’s next?

    The great news is that Stephen has already started working on a State Machine designer and its integration with XAF’s KPI module which gives dashboard its full power according to the man himself! Forgot to mention that a web version of Dashboards is coming soon!

    Big thanks to Stephen Manderson for sharing this cool XAF implementation with us, We welcome you to share your cool XAF stuff with the rest of us. Feel free to use our Support Center for this or our community project.

    Please do not forget to drop us a line about what we discussed today. Your input is very important to us

    Unit next time Happy XAF’ing as always!

    Download the XVideoRental sample here. The sample contains the following modifications

    1. A User friendly way to add permission migrated to the Common.Win.General namespace.
    2. XVideorental references the DynamicMemberAliases.Module from the Domain Components+ Calculated properties + Application Model.
    3. XVideorental references the ProvidedAssociation.Module from the Modifying Business Objects using Attributes.
    4. XVideorental references eXpand’s/Stephen's Dashboard module.

    Subscribe to XAF feed
    Subscribe to community feed

  • Domain Components+ Calculated properties + Application Model

    Updated 2/9/2013
    see end of post

    Even though XAF does not support the idea of Domain Components + Calculated properties + Application Model out-of-the-box, XAF is still designed with the highest of standards. In this blog, I will demonstrate hot to achieve this concept of Domain Component + Calculated Properties + Application Model otherwise.

    Domain Components

    With XAF it is possible to design business objects from interfaces! Given those interface DC with smart algorithms create concrete persistent class at runtime. It is possible to explore the DC dynamic assembly by overriding the in solution’s WinApplication descendant as shown:

    public partial class DynamicMemberAliases2WindowsFormsApplication : WinApplication {

        protected override string GetDcAssemblyFilePath() {

            return Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, DcAssemblyFileName);

        }

    Exploring the DC assembly for the following DomainComponent1

    [DomainComponent]

    public interface DomainComponent1 {

        string Email { get; set; }

        string Twitter { get; set; }

    }

    public override void Setup(XafApplication application) {

        base.Setup(application);

        XafTypesInfo.Instance.RegisterEntity("Manager", typeof(DomainComponent1));

     

    We find that XAF creates the next Manager class on the fly and that this class is a simple XPO persistent object and is specific to our DomainComponent1 (see the RegisterEntity method above).

     

     

    image

    This is really great! We already know how to create Dynamic member aliases though the Application Model and we can apply the same technique to the Manager class, which is very conveniently related only to the DomainComponent1. However, although the Dynamic member aliases can be successfully created in the Manager class, XAF would not know of their existence. In the next section we will discuss how to workaround this.

    The TypesInfo system

    1. In XAF, everything is an object. To help resolve object types, we created a TypesInfo system. XAF uses it for creating UI and for all the metadata operations. Because of how XAF was designed and because of the way TypesInfo system was built, metadata modification could be done easily.
    2. By default, XAF supports two ORM framework, XPO and Entity/ In addition, it is possible to integrate a custom ORM system. To make this possible, a separate interface, the ITypeInfoSource, which holds all the type metadata is available.

    UI + business logic <— TypesInfo –> XpoTypeInfoSource OR EFTypeInfoSource OR any ITypeInfoSource.

    Now we know that the XpoTypeInfoSource will retrieve Type members for any class from XAF. Therefore, we only need to override the EnumsMembers method of the XpoTypeInfoSource to provide our own implementation! Bellow is an excerpt of this implementation you can find the rest in the sample at the end of the post.

    public class XpandXpoTypeInfoSource : DevExpress.ExpressApp.DC.Xpo.XpoTypeInfoSource, ITypeInfoSource {

        void ITypeInfoSource.EnumMembers(TypeInfo info, EnumMembersHandler handler) {

            EnumMembers(info, handler);

            Type type = info.Type;

            if (TypeIsKnown(type)) {

                if (type.IsInterface) {

                    EnumDCInterfaceMembers(info, handler);

                }

            }

        }

    No doubt you too find this quick and simple? I always emphasize that XAF has 2 main advantages

    1. It is well architectured –> overridable.
    2. It is well architectured –> reusable.

    And since it is overridable and reusable you can download and use the DynamicMemberAliasesForDC.zip Winking smile.

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

    P.S. : The eXpandFramework users only need to register the Core modules (see How to use an eXpand module with an existing XAF application)

    Until next time, happy XAF’ing!

    Updated 2/9/2013

    In the next video, I demo how to create a calculated property in runtime.

    Subscribe to XAF feed
    Subscribe to community feed

LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners