eXpress App Framework Team

This Blog

News

You are welcome to test the new XAF features prior to the 17.2 release: one, two, three, four, five, five

May 2008 - Posts

  • XAF - 10 - Advanced data layer features

    This is post no. 10 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    I've reached the last post in the mini series, and this is going to be about the functionality XAF inherits from the underlying infrastructure that our ORM product XPO provides. For a start, this is where XAF gets its compatibility with a vast number of different database systems from.

    There are two different ways of changing the database type XAF connects to. The very easy approach, which we've implemented for a few of the most common backends, is to use the connection components in the Application Designer within Visual Studio. For backends that aren't directly supported by a connection type in the Designer, you must configure the connection string in the app.config and/or web.config file(s) manually.

    Of course it is important to know what connection strings you need to use. Generally I guess if you're using a particular RDBMS, you are probably more familiar with the connection string format it uses than I am, so in reality it's probably not a big problem. Your RDBMS docs should give you details, as well as online sources like http://www.connectionstrings.com/. For the purpose of using the connection strings with XPO/XAF, there's one other thing that's important though: the connection string format must be recognizable by our libraries, so they know what database type to connect to. There's a pretty useful heuristics at work to figure this out, but sometimes connection strings look so similar that the distinction isn't easy.

    For that reason, we have introduced a flag called "XpoProvider" into the connection string, which tells XPO explicitly which connection provider it has to use. The other extremely helpful thing is that all XPO connection providers have a helper method GetConnectionString, which takes a few typical parameters and generates a correct connection string, including the XpoProvider flag, for you. To take advantage of this, create a new Console Application project and add references to DevExpress.Data, DevExpress.Xpo and, if your provider is one of the less common ones, DevExpress.Xpo.<version>.Providers. The namespace DevExpress.Xpo.DB now has all the various Connection Provider classes, and you can output valid connection strings on the console like so:

    Console.WriteLine(MSSqlConnectionProvider.GetConnectionString(".", "mydb"));
    Console.WriteLine(MySqlConnectionProvider.GetConnectionString("localhost", "user", "password", "database"));
    Console.WriteLine(PervasiveSqlConnectionProvider.GetConnectionString("localhost", "user", "password", "database"));
    

    This example will render the following output:

     
    XpoProvider=MSSqlServer;data source=.;integrated security=SSPI;initial catalog=mydb
    XpoProvider=MySql;server=localhost;user id=user; password=password; database=database;persist security info=true;
    XpoProvider=Pervasive;Server=localhost;UID=user;PWD=password;Data Source=database;

    In addition to this, XPO also supports connecting to a service of some description, over a remote connection. Over time I've written a whole lot of blog posts on this topic, which I recommend you read if you're interested in this scenario. Here's the main XPO blog, which you should probably read through yourself. Here's an incomplete list of the interesting posts on the subject:

    The connection strings that make XPO connect to XML Web Services and .NET Remoting are also supported by XAF directly.

    Finally, if you want to influence the way the XPO connection is set up and do things you can't specify through the connection string, it is possible to hook into the process of setting up the XPO connection provider and data layer. To do this, you override the method OnCreateCustomObjectSpaceProvider in your WinApplication and/or WebApplication class(es) and return your own version of an ObjectSpaceProvider. It isn't hard to derive your own ObjectSpaceProvider from one of the standard ones and handle data layer creation in any way you see fit -- if there's interest in this and reading the source of ObjectSpaceProvider.cs doesn't help you, leave a comment and I'll try to create a sample when I have time.

    Some other interesting features of XPO that you could enable or configure using this approach are the data layer caching and SqlDependency features. Of course you can switch on SqlDependency support by using the right XpoProvider flag, as described in the article, and this also enables data layer caching. But SqlDependency is a special feature for SQL Server support, and setting up data layer caching for other backends currently requires the OnCreateCustomObjectSpaceProvider approach outlined above.

    So, that's all I have to say today. I hope the series was interesting -- I'll hand the post on styling ASP.NET applications in as soon as it makes sense, again my apologies for that one. I'm almost on my way to TechEd now -- if you're there, say hi!

  • XAF - 9 - Styling ASP.NET applications - delayed

    This should have been post no. 9 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    Well, it's not. I decided to post this anyway to let those who've been following the series know that the ASP.NET styling post isn't going to happen right now. I looked into the whole styling thing for a while and I found that our story in that regard is much weaker right now than I thought it was. So no excuses -- I'll follow up on this, we're going to improve things and I'll blog about the topic when it makes more sense than it does right now. My apologies for this.

    Meanwhile, if you're interested in finding out what we have to say about styling, your best bet is to search our knowledge base and support center, both of which contain some information on applying ASP.NET themes to an XAF web application.

  • XAF - 8 - Add your own UI parts

    This is post no. 8 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    The message I'm trying to convey today is really very simple: if there's something you can't do within the boundaries of XAF, it is still possible to do it (partly) outside.

    As I know from personal experience, frameworks often have what I like to call a lock-in effect. Basically, you write an application based on some framework, and suddenly the customer comes along with this requirement that just doesn't seem to be possible within the framework architecture. Often this has to do with the way the framework works -- for instance, systems that are based on code generation often make it pretty hard to add extensions beyond what the framework authors had in their minds. In other cases, it is simply not possible to work with the framework's data structures, but outside its UI elements. There are lots of other problems -- it's simply something that is very common to encounter.

    In a way, these lock-in effects are unavoidable. Every framework is created for a particular purpose, standardizing certain things in order to make them easier to use, but at the same time imposing restrictions on what can be done at all with reasonable effort. If you start working with XAF and then decide that the application you're writing really has all the characteristics of Doom II, then there's not much we can do to help you. Outside of that, XAF is quite exceptional in its openness. Avoiding the lock-in effect was something we targeted specifically in the XAF architecture, and if there are cases where we haven't succeeded yet, feel free to let us know and we'll do what we can.

    The title "add your own UI parts" of this post is about creating new pages or forms in your applications that work with XAF data, but are simply (Web)Forms for one or the other UI platform. The important part of doing is to access data that is, by default, handled by XAF automatically, in order to work with it as you see fit in these parts you've created yourself. This is surprisingly (?) simple in XAF, basically you just have to get hold of a reference to the current running application, and you can access all the data handling classes from there.

    In the ASP.NET application there's a singleton instance of the running application available through WebApplication.Instance, in the Windows Forms one there's currently no such thing -- a slight oddity I found myself when I looked into this. We will probably change something about this in the future, meanwhile you can either add your own static property to the WinApplication class (that class is declared in your code, after all), or you can pass the reference in from the controller you use to bring up your custom form or otherwise call into your custome code. A controller is the likely link you will use anyway between "standard" framework based code and your own, and the reference is easily accessible from there, so this shouldn't really be a problem.

    I'm attaching a sample application to this post, which implements a custom Web Form as well as a custom Windows Form. There are controllers and actions in both applications that you can use to jump into the custom parts. The action for the ASP.NET example is available everywhere (button on the top right above the standard list view), the one for the Windows Forms sample is configured to apply to Post type objects.

    Click here to download the sample application. Have fun!

  • XAF - 7 - Take advantage of the UI abstraction

    This is post no. 7 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    As you know if you've had a look at our XAF pages or tried the product yourself, there's a layer in XAF that allows you to develop applications for the Windows Forms and the ASP.NET UI platforms at the same time. All your code can live in the UI independent module and XAF takes care of the UI specific representation. Of course there are lots of cases where certain UI specific changes need to be made, but this is also easy to do within the solution structure, because it includes projects that specifically target each of the supported platforms.

    Reaching this degree of UI independence we have was an important target for XAF from the beginning. Of course there will always be platforms that people use at the same time -- i.e. it makes sense sometimes to have a version of an application that runs on ASP.NET and another one that uses Windows Forms --, but we also make our product and the code you write on the UI independent level a much safer investment.

    The world around UI technology evolves pretty quickly these days. As an example, it's not too long ago that Windows development was focused on Win32. For many use cases, Windows Forms abstracted enough from that old world to make things a bit easier for developers, but WPF is really the first UI platform that doesn't inherit an API that is, in parts, more than 15 years old. Still, from a Microsoft developer's perspective, the time that passed while Windows Forms was the primary platform of choice for client development was already considerably shorter than the ActiveX period that came before it (or the Delphi period, if your that way inclined). Personally I do believe that WPF is going to be very significant for an extended period of time, but if we have a chance of abstracting our business development efforts from these uncertainties, why not take it? Regardless of what your thoughts are on WPF, Windows Forms, Silverlight, ASP.NET, UI specific software factories, AJAX, the whole old web vs client discussion.... wouldn't it be great not to have to consider these things anymore?

    Perhaps we can't promise that all these issues will be entirely irrelevant to your development forever. No, we certainly can't promise that. But what we're trying to do is, once again, to save you significant effort by doing a lot of your work for you.

    Abstraction from the UI doesn't come for free. It has a price in two different areas: (1) abstraction and (2) working with a least common denominator as a feature set. To an extent it is possible to make abstraction comfortable to use, and it's also possible to enlarge the common feature set by making the abstracted technology more intelligent, basically leveling the playing field by filling in gaps where necessary. Of course this latter approach also means that any new UI platform will be harder to target, depending on the gaps it has. It is, and will always remain, a fight for the perfect compromise.

    In real world applications there are several different scenarios where it makes sense to have UI abstraction:

    • You need the same application to run on two different platforms. For instance, you could have a richer native UI that people use locally, while others access a web UI from outside the company.
    • You have slight variations in the two UIs, for instance in the case where the "external" version of your application, using the ASP.NET UI, doesn't have all the same features as the "internal" Windows Forms based one.
    • There are two very different UIs in use, but both work against the same objects/database and business logic. An example of this would be a web system with a Windows Forms management frontend. In this case you would probably have to/want to design the web frontend in a non-standard way, as far as XAF is concerned.
    • If you create UI modules or UI based functionality for a particular vertical solution, you can create this domain specific functionality in a way that enables it to be used on two UI platforms -- by your customers or other departments in your own company.
    • You can implement certain generic functionality in your application on the UI independent layer.

    There are classes in the DevExpress.ExpressApp.Editors namespace that allow you to access common functionality of UI elements without actually introducing UI dependencies into your code. The MainDemo included in our XAF distribution contains a few controller examples (in the Module project) that use these classes to provide common functionality -- clearing fields in a detail view is one such example.

    I didn't put it many links in this post, since I believe this is more about the general consideration of whether or not, and when, UI independence makes sense. As I said before in another post -- in the end it's your choice. XAF also lets you create projects specific to one of the supported UI platforms, if that's what you prefer. My personal belief is that UI abstraction is moving from a convenience to a necessity these days, and that belief is well reflected in the way XAF works.

  • XAF - 6 - XAF Extensibility Points

    This is post no. 6 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    XAF is a highly modularized and extensible platform. This is quite obvious as soon as you start creating your own application based on XAF -- there are lots of standard modules that add functionality, there's the way XAF picks up elements you create yourself and makes them part of your application. What does extensibility really mean with regard to XAF?

    Generally there are two ways people think about extensibility. Looking at your own applications, this might be easy for you to see or hard, depending on the approaches you've been using. If your projects are the kind where you create some forms or pages in VS, drop UI elements on them and hook up a few events, then extensibility with regard to your own applications is probably quite meaningless to you. On the other hand, if you have a few helper libraries with reusable functionality that you utilize across various projects, or if you've even developed your own framework in the past, you'll easily see what extensibility on the application/project level is about: the ways you have to extend the application beyond what the framework offers out of the box. If one of your helper libraries facilitates data validation, how easy is it to create application specific validation for a particular project? If your framework creates type specific data entry forms for you, how easy is it to modify these if the need arises?

    When a certain question of extensibility on the application level comes up a few times, you start thinking about extending your framework or helper libraries instead of making project specific changes all the time. That's the second level and usually it's a lot more abstract since you have to think about more than one use case at the same time. You might also decide that extensibility in some areas is better left on the application level. Certain visual case-by-case approaches to solving application level problems can be very hard to abstract in a meaningful way, so that the advantage of having framework functionality is offset by greatly reduced ease of use.

    In XAF, extensibility is often on the framework level. At the same time, we feel pretty confident in saying that extending on the framework level in most cases doesn't result in added abstraction to the extent where it costs you a lot of additional time to do it. Basically you are doing per-project work, only with the added benefit of reusability across projects. The reason for this is the strong structure an XAF solution has by default:

    1. The Module project is UI independent, so it is clearly the place where most functionality should go, if possible.
    2. Our UI abstraction layer makes this convenient for a large set of use cases that would otherwise be UI specific.
    3. Additional modules specific to the two supported UI platforms provide other places to put UI specific code.
    4. Many existing modules add functionality orthogonally
    5. It's a psychological thing -- the way the platform works is the natural way to go for your own extensions

    Of course, in the end it's your decision -- if you want to add your extensions all over the place, go ahead! :-)

    Now, on to something more practical: a list of extensibility points in XAF. I'm probably forgetting something, but I hope this list is still an interesting summary.

    • The Validation System is extensible, I've covered this before in post 3 of this series.
    • It is possible to make your own controls (or other 3rd party vendors' controls) work with XAF. There are several examples of this in the XAF documentation, http://documentation.devexpress.com/#Xaf/CustomDocument2659, http://documentation.devexpress.com/#Xaf/CustomDocument2679 and http://documentation.devexpress.com/#Xaf/CustomDocument2678. There's also a demo that gets installed with XAF (in the Demos subfolder of your installation) that implements the custom editors described in the documentation.
    • The XAF Security System is extensible in many different ways. It uses separate strategies for authentication (based either on your own database or Active Directory) and authorization (simple and complex). For each strategy we currently deliver two implementations out of the box and you can create your own. We have several permission types and it is also possible to create your own permission types to use with our Complex Security implementation. Mostly those things involve creating your own class derived from one of our base classes and making sure it's instantiated in the right place. There's some info about this in places in the documentation, but we definitely need samples for this -- right now I'm afraid the source code is your best friend (not a bad one, mind you, but still not quite something that fulfills my quality expectations).
    • The Application Model is extensible, so you can use it to integrate your own application or module specific options and benefit from the functionality the Model offers, such as localizability. This is probably most interesting if you create your own modules to give to others, or at least to reuse in a large variety of different projects.
    • XPO, the object/relational mapping system that is the basis of the data persistence functionality in XAF, has an abstraction of the "drivers" used for the actual database access on a low level. There's already a very impressive collection of almost 20 different such "providers" included in XPO, and these are abstracted so well that the file size of the largest provider implementation is currently at only around 30000 bytes (the smallest is just 6207 bytes, btw). If you are interested in creating a provider to hook up with a database system we don't support yet, I recommend you have a look at the existing source code -- it might be much easier than you think.

    Right, I'll stop at this point. As I said, there's probably something I'm forgetting, and as I described above, the definition of what constitutes an extension to a framework is not entirely cleary anyway, so I'm sure there are a lot of things that I could mention here. Feel free to suggest additional extensibility related entries for this list!

  • XAF - 5 - Go do it! Action types and options

    This is post no. 5 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    As soon as you've written some application specific business functionality, the next important step is to make it available to the end user through the application UI. For this purpose, XAF supports Actions, which are represented by UI elements, depending on the target UI of course.

    Simple functionality will sometimes live in the business classes themselves, and the easiest way to make this accessible through the UI is to create public methods in the classes and decorate those with the ActionAttribute. XAF will then create an instance of the SimpleAction type for you, together with some framework stuff that you'd otherwise have to create yourself. Using named parameters of the ActionAttribute, you can configure quite a few of the properties that the resulting SimpleAction has.

    However, using the ActionAttribute gives you only so much flexibility, and in many cases it doesn't seem like the right solution to have more complex code live in public methods on a particular persistent type. In these cases you must create actions yourself in one or more controllers. XAF currently knows WindowControllers and ViewControllers, both of which can be easily created using Visual Studio templates that are installed with XAF (note that Actions are usually UI independent, so you should add your controllers to the UI independent xxxx.Module project in your solution!). The controllers can be used for many different purposes, some of which require you to write code and override methods from the base classes. In the case of actions you'll have to use design surface though, so bring it up with a double-click on the controller entry in Solution Explorer. In the Visual Studio toolbox you will then find the (currently four) different action types that XAF installs.

    One of the most important things about these standard action types is that they all offer a variety of options that make them much more versatile than you'd think at first glance. Here's a summary of the four types -- this documentation here is actually very good, read the whole page carefully to pick up all the details. Especially don't skip the part about the members of the ActionBase, since it describes what you need to know about properties like ConfirmationMessage, Category and others!

    1. The SimpleAction is visualized as a Button and it "simply" invokes its Execute event, from where you can call your business logic.
    2. The SingleChoiceAction displays as a combo box or a tree. The latter can be used to display hierarchies of menus, where each entry is an executable element in its own right. With the combo box display, the action allows the user to select one from several elements (the docs call this an "operation mode", which captures the idea quite well).
    3. With the ParametrizedAction, the user can enter information in a text editor before invoking the action. A search function would probably be the best example for what this looks like -- the standard search functionality that XAF applications contain is implemented like this.
    4. Finally, the PopupWindowShowAction is the most complex and flexible type, as it brings up a window containing a standard XAF view before the action is executed. There's a special event that allows you to customize the view so it displays the exact data you want.

    The tutorial application has examples for most action types, and it also gives information about other important details, like how to disable an action selectively.

    That's it for today, about actions. This is a very important part of XAF, and also one of the more complex ones. As you might have noticed, most of links in this post go back to our product documentation -- there are a lot of details about actions, and I strongly advise you read up on them to see what the framework offers in this regard.

  • XAF - 4 - General purpose standard modules

    This is post no. 4 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    One of the main ideas behind XAF is to make the framework do lots of the work for you that you would otherwise have to do manually, even though it's tedious repetitive stuff. Of course everybody knows that if you find yourself implementing certain functionality more than once, you should abstract it into a separate library in order to reuse it across projects and use cases. In reality, this step is often not made, for a variety of reasons -- the basic ones are that it takes time and the customer isn't really paying for the time you spend creating a great reusable architecture for your next customer to benefit from.

    On the other hand this is something we do very well here at Developer Express. Our products are meant to be useful in many different scenarios, and the functionality we provide is based on an architecture abstract enough to facilitate adaptation to all those scenarios. In a way, this was the subject on the interesting recent discussion you can find here, because this separation of concerns does influence what we do and what we expect/need our customers to do -- probably in XAF more so than in our single component products.

    This post is about a certain group of standard modules we deliver. Some of our modules have very specific features (like the Scheduler module or the Reporting module, but others are more general purpose and make sense in almost all XAF based applications. However, these modules are not active for new solutions by default and you'll have to activate them in the application/module designer to take advantage of them. One of these general purpose modules I have already described in my previous article about Validation, here are a few more now.

    The first module I want to point you at is the ViewVariants module. This module allows you to create variations of view configurations that the end user can switch in the running application -- in both UI platforms of course. The tutorial at the link above shows how to activate the module and how to configure additional view variants. It's important to point out that this is not restricted to few or many columns (the example chosen in the tutorial). You can (re-)configure everything there is to configure about a view in any of the variants. This feature is typically used to provide several different views of the same data, and it is very important when data is consumed by people in many different roles -- from the person who enters information in all columns to the controller who needs subset of the information to the executive who wants only the summaries.

    Second on my list is the Printing System module. If you've worked with our components before outside of XAF, you'll recognize our XtraPrinting Library product in that name, and indeed the functionality is that which XtraPrinting provides. Why is that important? Well, it has happened to myself in the past: you have this great product planned with your customer, you have data entry functionality specified, business processes documented and somebody has drawn sketches of the reports. Great. You implement everything and test it and you see that it's fine. The first real user (as in the first person who wasn't involved with the whole prior process) gets his/her hands on the thing and says, "right, so how do I print this data entry grid?" Hm. When I first used the Printing System back in Delphi days -- Delphi 4 or 5, I think -- to work around this exact problem, that was one of the biggest real-world time savers I'd seen to that date.

    Third, the security modules. Probably even more important than the other two above, I'm not going to say too much about them because they are especially well documented and also somewhat more obvious than the others. Security covers a lot of ground right now, from basic "once-in-do-what-you-want" setups to pretty detailed per-type permissions, with two different types of authentication. It's extensible as well and we're going to extend it in the future to cover more scenarios.

    Now, at this point we're slowly moving towards those modules that are still more general purpose than the example of the Scheduler I gave above, but at the same time you might not decide to use them unless you have a specific requirement for them. I guess you could say that while the first three were things to strongly recommend even without a requirement, the next few respond to common requirements that you're very likely to have. So here's a somewhat shorter reference to these next four:

    1. The FileAttachments module handles files that are attached to objects (duh!). This is a pretty common use case and so we decided to make it as easy as we could.
    2. With the help of the CloneObject module, the end user can quickly create copies of existing objects.
    3. The Conditional Formatting module can mark up list view content according to rules you configure in the Application Model.
    4. Tracking everything that happens on the object level, changes, creations, deletions... is fully automatic with the Audit Trail module. In certain vertical markets this is extremely important, in others probably less so :-)

    Great, that's it for this topic. We will certainly continue creating new modules as development on XAF progresses. It would be nice to see general purpose modules created by our customers at some point -- we'll get there, I'm sure.

  • XAF - 3 - Validation and what (else) you can do with it

    This is post no. 3 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    The Validation module in XAF is probably one of the most important functional modules we offer, and with its flexibility comes complexity. Documentation about the module is pretty complete, but I'm going to link to the most important topics from this article and try to summarize various considerations about data validation in general.

    Validation of data through the module is usually achieved by applying RuleXXX attributes to either persistent classes or their properties in code. There are currently ten different rule types we deliver with XAF, and each of these has a corresponding attribute. Some rules implement pretty simple value restrictions, like the RuleStringComparison or the RuleRange. Others allow for more complex checks across types, like RuleIsReferenced or RuleObjectExists. Finally it is also possible to apply any XPO compatible criteria through RuleCriteria (hint for that last one: if you need help writing those criteria strings, try reading this docs page and this docs page and also this blog article).

    Note that the attributes in code aren't the only way of applying rules. It's also possible to use the Validation node in the Application Model to configure them. This makes it possible to leave certain aspects of the rule configuration for the time when the application is deployed to the customer's site.

    These validators we deliver out of the box do a pretty good job of covering all the basic scenarios, but when we created the system, we were also expecting people to check more complex scenarios. This is business logic we're talking about, and of course we can't implement it for you. So we made the validation system extensible. When researching for this article, I found that we have a certain lack of documentation and samples for custom validators - there's a sample I created myself in the past, you can find it attached to this forum post. I'll try to get some more material created about this in the future - it's not really hard to do though, since it's basically one class with one overridden method you need to implement (and a second class with boilerplate code to make the rule accessible through an attribute).

    Validation in our system always happens according to contexts. This is based on the understanding that validity is not something that can be determined absolutely - in reality what we want to check is fitness for a particular purpose. When I wrote the original user stories for our Validation module, I was going to call it Plausibility Checking instead, in order to reflect that fact. Somehow that name got dropped through lack of use though... anyway, contexts. Every time a rule is applied, it is associated with a context. The context in turn is just represented by a string, a context ID if you will. Technically, there are no contexts in XAF that are built in. There is a standard controller though, which checks two default contexts we deliver, named Save and Delete, and for convenience we also have a DefaultContexts class that makes it easier to apply these contexts correctly.

    Now, the important thing to realize is that you can have as many different contexts as you like, and check them whenever you like. The "standard" contexts are automatically checked through a controller class, and you can do the same thing for your contexts if you want. You can also just check them when a certain Action is triggered, for instance, or at any other point. Here's the documentation about custom context checking..

    That's almost it already - I'm surprised this article isn't longer :-) But there's one other thing I want to mention: an interesting discussion I posted a while ago about the meaning of "partial" validity (here's a followup to the first post).

  • XAF - 2 - Customizing the default applications

    This is post no. 2 in the mini series "10 exciting things to know about XAF". You can find the announcement of the series here.

    In the process of creating applications based on XAF, the next step after the creation of business classes is the customization of the default applications XAF creates automatically. In many cases XAF will provide you with defaults that are as reasonable as we could make them, considering the vast numbers of different scenarios we target, in other cases we simply create something as a basis that you will have to modify for almost all applications. At lest for Windows Forms, the default container forms we use are an example of something we expect you to use as is most of the time, while for instance the layouts of the detail views will almost always be subject to change according to your application's requirements.

    The largest part of customization work for XAF based applications is done in the Application Model. The Application Model is a centralized, hierarchical configuration store, which is initially filled with information gathered from a metadata analysis process in the framework. In a second step, changes to settings from the Application Model are merged in from several different sources, thereby overloading the defaults. Since the sources that changes are loaded from depend also on the application being run -- i.e. WinForms vs. ASP.NET -- it is possible to target a particular UI platform with certain settings. The Application Model is extensible, so that XAF modules can integrate their own settings into the hierarchy. Having all UI generation settings centralized in this way enables us to provide functionality on that basis, and the prominent example for that is the great localization support in XAF. You can find additional information about the Application Model here.

    During the metadata gathering process, the framework finds a variety of different class types in the compiled assemblies and extracts information from those. The first way to change settings is to decorate classes with certain attributes that will be recognized by the algorithm and translated into model settings. While this is a pretty simple step, we do see a certain amount of confusion over this - it is important to realize that code attributes and model settings are, in many cases, just two different ways of achieving the same results.

    XAF tries to provide application developers with a framework that lets them focus on that code which is really particular to their current project, which implements specific data storage classes, business logic around those classes and other functionality that is part of their requirements. We found it a natural consequence of this philosophy that developers should be able to configure the most important details about their classes using a code-based approach. That's why we introduced attributes in some cases that overlap with Application Model settings. Compared to code-only configuration, this adds a good amount of additional flexibility of course.

    The easiest way to work with the model directly is using the Model Editor. At design time this is integrated fully in Visual Studio and can be brought up by double-clicking one of the files with an .xafml extension (see here for more detailed instructions). (Note that depending on the file you're editing you will modify settings either for both UI platforms at once or a particular one.) These are the most important nodes in the hierarchy, in descending order of importance:

    • The BOModel node contains one subnode for each persistent class in your project(s) (up to the level on which you're editing the model). The settings in these nodes allow you to configure lots of parameters for the appearance of the classes in the UI.
    • The Views node is where you customize the layout of the list and detail views for each data type. Be sure to click on the root node of each view to bring up the layout editor at design time! This is probably one of the most often missed features in XAF.
    • The CreatableItems node has entries for those types that can have new instances created at runtime through the New action. You can either remove nodes here if you don't want a type to be creatable in this way or you can add nodes if you want to make classes creatable that aren't by default. Classes that have either the DefaultClassOptionsAttribute or the CreatableItemsAttribute applied (in the latter case with a true parameter), get CreatableItems nodes created by default.
    • The NavigationItems node contains nodes for each class type that appears as a major navigation entry in the default UIs. In Windows Forms this is a button in the navigation bar on the left-hand side of the window, in ASP.NET a tab in the top part of the pages. You can modify these nodes in a similar way to the CreatableItems nodes, and the default set is constructed from those classes that have either [DefaultClassOptions] or http://documentation.devexpress.com/#Xaf/clsDevExpressPersistentBaseNavigationItemAttributetopic applied.
    • The Options node is a node for assorted options supplied by the various modules. It's content depends on which modules are currently active in your application.
    • The Application node provides general settings for the application.
    • The Validation node is specific to the Validation module, but there will rarely be a business app out there that doesn't use validation one way or another. More on validation in article 3 of the series. In spite of the importance of the validation feature, it's not too common to have to change validation settings in the Application Model, that's why this entry is not at the top of this list.

    While it is possible, and certainly common, to configure the Application Model at design time, its architecture also allows making changes at runtime. To some extent, this is even expected -- when an end user changes the order of columns in a grid, for instance, these settings are persisted in a file that is "part of the model" since it's read back into the model for the next application run. As developers, we can also use this feature by making changes at runtime. It is possible to bring up a standalone version of the Model Editor at runtime, and other changes, like certain control settings or layout changes to detail views, are persisted as Application Model "diffs". The only downside to this approach is that you'll have to merge the changes back into the design time .xafml files manually -- cut&paste in a text editor will do it, but that's still not everybody's thing.

    Right, that's pretty much all I have to say for now. There are certain other topics that fall in the category of customizations to the applications, such as utilizing additional standard modules or How to: Customize a Template, but beyond the links to our product documentation these are topics for another day.

  • Exciting things about XAF not exciting enough?

    I've heard some criticism about the first post in my 10 exciting things to know about XAF series: apparently it's not exciting enough! Well, let me tell you: the day that we don't receive a single support request about the matters I mentioned in that blog post will be the happy day where I agree that this is a boring topic.

    If you can honestly say that you understand everything I mentioned and you observe these practices in all your projects (or at least that you have spent a lot of time making a decision and you have good reasons not to follow the practices), then that's great -- more power to you! But... (a) the series is targeted at new users of the technology to at least the same extent as existing users, (b) there wasn't any overview like the one I created before and we get enough feedback asking for that kind of summarized "what do I need to know" information and finally (c), and I don't mean this condescendingly, the majority of our users are somewhere on the curve as opposed to at its end.

    It's all about the learning curve here -- one of the comments we hear about XAF most is that it has such a very steep learning curve. To be honest, I don't really agree with that statement, since it is often made when people throw large independent "blocks of knowledge" in with their product-specific learning. Learning XAF is easy, assuming you have strong OO programming knowledge. It seems hardly correct to say that XAF has a steep learning curve if the knowledge that's really so hard to come by is largely not specific to XAF. But be that as it may -- my target is to help everybody get to the same level, and in order to do that we need lots of content in various different formats, we need to make it accessible and discoverable, and often we need to be repetitive as well.

1
2
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