Tag Archive for 'DevExpress' Page 2 of 3



Developer Express has announced DXperience 2008 vol 1 beta

There are quire a few breaking changes for this one, although they seem to be just minor things.

List of changes in this version is available as well.

A couple of remarks on the changes:

  • Rich Text Editor for ASP.NET 2.0 (Desktop version is probably lurking around somewhere as well)
  • TreeView-Grid Hybrid for ASP.NET 2.0
  • Some unit tests have been made available. That’s the step towards improving development experience of customers. One can feel himself more safe while making changes in the code with test coverage.
  • Desktop UI has got cute apple skin. Additionally ASP.NET controls have got consistent theming support.
    DevExperience apple skin
  • Linq Server Mode has been mentioned a few times.
  • eXpress Application Framework changes are surprisingly limited. It feels like the development team has been assigned away from the project.

One more usage of the XtraLayoutControl - cross-platform UI designer

DevExperience has a nice control called XtraLayoutControl. Basically it allows you to have your own form designer at run-time.

XtraLayoutControl in action

But it can easily do more than just reshuffling of existing items for the Desktop UI. You can design forms that will be rendered on Desktop and Web alike.

eXpressAppFramework team has started using its capabilities of the design management, but I believe they can go even further if they:

  • Forget about pseudo-groups with custom orientation flags and keep positioning and size information of the design elements.
  • Add a couple of simple layout elements that are stored in the layout only (i.e. LayoutLabel, LayoutImage).
  • Use full design information for rendering detail views on the Web.
  • Forget about the model and persist the design in the DB.
  • Actually it is quite easy to go even further on this read and push all view schemas, data schemas and even form storage schema (if they implement Forms) to the database (thus allowing to change all that on-the-fly).

All the above items are quite easy to implement. I know that for sure since they constitute logically separate module in xLim 2 - “Record and Form Management” (Flexible Grids + Details + Forms) and that has already been done more than once.

There’s even more of that. I believe that the information generated by the XtraLayoutControl is enough to create similar interfaces not only for Web and Desktop, but for WPF and GTK# also (would not you want to have the perspective of reusing your nicely crafted forms on Linux platforms?)

Desktop UI Form produced by XtraLayout designer

Web UI Form produced by Xtra Layout designer

Using skins to distinguish between different build/configuration types

The most appealing way to distinguish between development, test and production versions of your desktop and web applications is to use different skin for each one.

Normally, people tend to miss connection strings, application titles or version numbers. Or, it could be an extra burden for non-dev people to memorize things like: “If there is TEST within the title bar and the connection string in the status bar points to http://test…, then this is snapshot and you can do whatever you want to.”

If the entire application has nice Caramel skin for the test version and professional Office outfit for the production, then it would be quite hard to get confused with that.

DifferentSkins

All you need is:

  • Integration server managing “Test” and “Release” releases (and any other type of build)
  • Different config sets under version control (normally these should be stored in a secure SVN repository separately from the “Trunk”)
  • Component suite that supports simple skinning (like DevExpress)
  • Some flexible configuration system (Autofac’s own config is perfectly fine for this purpose)

If you have all these (and you normally should) then it would take just 10 minutes to enable “different UI look for different build type” feature.

Running xLim under Mono 1.2.6

There’s a small update to the last post on xLim portability. The situation is a bit better than it seemed to be.

XPO + Mono (SUSE SLED)

XPO runs under Mono. It can’t work with the the Microsoft SQL Provider since the MS SQL support under Mono is far from perfect for obvious reasons. MySQL provider does work but, as developers have found out, you’d need to change

string[] strArray = (string[])new ArrayList(dictionary.Keys).
  ToArray(typeof(string));

to

string[] strArray = new string[dictionary.Keys.Count];
dictionary.Keys.CopyTo(strArray, 0);

in the XPO sources in order for the distributed caching to work. That’s because dictionaries in Mono do not have full support yet.

Autofac + Mono (SUSE SLED)

There are 6 unit test failures:

BugFixture.IncorrectExceptionThrown1
Builder.ConcreteRegistrarFixture.RegisterThreeServices
Builder.ConcreteRegistrarFixture.
  RegisterTypeAsSupportedAndUnsupportedService
Component.Registration.ContextAwareDelegateRegistrationFixture.
  CreateFromStrongFactory
ContainerFixture.IntegrationTest
DisposerFixture.ReferenceNotHeld

Additionally there is an issue while using binary remoting across the platforms (from SLED+Mono to .NET Windows and vice versa). DateTime cannot get through, for some reason.

Theoretically, Autofac, XPO and the design with the portability in mind is all you need in order to create xLim server and engine functionality that works on Mono. So we’re in good shape here for the xLim 3 server prototypes by summer.

Web UI has got some chance of being implemented quite soon in a performant manner as well (Silverlight grid, as stated in “DevExperience Roadmap 2008″, could be delivered on summer). Additionally there is some chance that existing ASP.NET controls would work under Mono as well.

The picture for the xLim Desktop UI under Mono so far is still the same - there are no DevExpress controls any time soon, unless Silverlight grid would be capable of running on desktop. But that’s just a tiny fraction of the required UI bits.

One more usage of scopes and micro-controllers in composite applications

This post does not belong to the primary body of knowledge within autofac or xLim series.

It expands on the last article about IoC scopes and application composition and attempts to provide quick proof of concept answer (POC) to one question from the DevExpress Forum on XAF about implementing security scenarios.

Let’s talk code:

public sealed class ContextSecurityController : ICommand
{
  private readonly GridParameters _parameters;
  private readonly IIdentityObject _parentObject;
  private readonly IGuidIdentity _user;

  public ContextSecurityController(GridParameters parameters,
    IIdentityObject parentObject, IGuidIdentity user)
  {
    _parameters = parameters;
    _user = user;
    _parentObject = parentObject;
  }

  public void Execute()
  {
    string s = _parameters.CriteriaString;
    if (!string.IsNullOrEmpty(s) && s.Contains("#{"))
    {
      _parameters.CriteriaString = s
        .Replace("#{AccountId}", _user.Id.ToString())
        .Replace("#{ActorId}", _user.Owner.ToString())
        .Replace("#{ParentObjectId}", _parentObject.Oid.ToString());
    }
  }
}

In this scenario this controller should be resolved in the view scope and executed once (yes, it has the ICommand interface, since it is just a command). Upon execution it attempts to parse the XPO criteria string and modify it a little bit.

Here are the steps to make this work within the current xLim concept:

  • Add a comma-delimited list of start-up command names to the base ViewParameter object
  • Add 3 lines of code to the base view object when it loads the parameters (string.Split(Current.StartupCommands) - foreach - ResolveByName - Execute)
  • Configure the views to call this command/controller on startup.
  • Make sure that the views, dealing with the data, pass the instance of the parent object to the scope
  • Make sure that all the BOs inherit from IIdentityObject (I always do this, since this helps to provide ability to bind memos, documents, forms etc to any object in the system)

Then you could use criteria strings like:

  • Document.CreatedByOid=#{AccountId}
  • Employer.Manager.Oid=#{ParentObjectId}

Side effects:

  • Any desktop or web view will get the ability to have configurable commands executed on the start-up (commands normally do not care about the UI)
  • Since any application already has a huge list of commands in the library, you could re-use these, too.

This controller is extremely simple to extend with the support for more complex tokens (i.e.: #{DateTime}, #{CurrentOfficeId}, #{SecurityHash} etc), you just need to make sure that the values do not mess up the syntax of XPO. Or you could implement more complex parser that takes the named object from the current scope and evaluate some property of it. You’ll get the simplified scripting in that case.

One more option is to use the DSLs to express complex business requirements (although, I would not advise to do that).

PS: This approach seems to be simple and flexible, and yet it is not recommended for the xLim 2 implementations. Too much of flexibility in the wrong spot is not a good thing for the project in the long term (been there, done that). This post serves POC purpose only.

xLim portability issues

As you know, one of the long-term “nice-to-have”s of the xLim 2 architecture is the ability to run web/server/desktop/engine pieces under the Mono environment (and this would open new OSes as targetable platforms).

Given the dependencies of the current xLim version, efficient desktop cross-platform compatibility for desktop client apps is yet out of the reach:

  • DevExperience WinForms components are never to run under Mono (heavy PInvoke dependencies are the payment for the beautiful UI). Try running MoMA to see that yourself. Although I would really miss only the XtraGrids piece (and these have a decent chance of being re-implemented under Silverlight).
  • Pure GTK# and WinForms client apps could do the trick but they neither feel nor they are efficient to use.
  • The best long-shot would be the WPF-based architecture with the cross-platform support for the Silverlight (or full-blown WPF) UI, but this is yet to come (and there’s still some uncertainty with that)

So we have web/server/engine pieces that could be made Mono-compatible in the mid-term. The situation is good with these. Mono web servers successfully host ASP.NET starter kits and different web services. And if DevExperience.Web has some portability issues, then it could be ditched. The only piece that I would really miss is the grid again (and there’s that “Silverlight-to-the-rescue” thing again).

Services and remoting do work under Mono with some quirks (binary compatibility for the cross-platform remoting is there also), although GC for now might be far from being perfect.

There are two major obstacles on this way (and they come from the major dependencies):

  • Autofac IoC compatibility with Mono
  • XPO compatibility with Mono

Luckily autofac is almost there (there are just some tests that fail under Mono).

XPO is in worse shape. It does not run at all. Luckily Mono Migration analyzer does not have a lot of arguments with the XPO code (some of these could be completely ignored).

Well, we’ll see. The good thing with the “nice-to-haves” is that they deal with the future probabilities and thus their effect on the present architecture is rather flexible.

PS: If you are interested about the reasoning behind the business need for cross-platform support xLim, then you might want to check these posts:

How to implement complex UI composition in xLim?

Here’s another post that continues the topic of xLim extensibility and originates from Ayende’s blog. He has posted on an interesting problem of view composition. Here’s quick possible solution for the initial problem within the xLim 2 concept:

1. Define reusable composite view that is just a wrapper for the list of views and their parameters

public sealed class CompositeView : DesktopViewBase<CompositeViewParameters>
{
   protected override void OnLoad(CompositeViewParameters parameters)
   {
      Parameters = parameters;
   }
   public CompositeViewParameters Parameters { get; private set; }
}

2. Define reusable CompositeDesktopWorkspace class that can take any number of controls as an argument and create PanelWorkspace for each one.

public class CompositeDesktopWorkspace :
   Workspace<CompositeView, IViewInfoReader>
{
   public CompositeDesktopWorkspace(Control[] containerControls)
   {
      _workspaces = new IWorkspace[containerControls.Length];
      for (int i = 0; i < containerControls.Length; i++)
      {
         _workspaces[i] = new PanelWorkspace(containerControls[i]);
      }
   }

When asked for a view, CompositeDesktopWorkspace should load it. Load operation will fail if the view being loaded is not CompositeView, although one could add logic that will simply load any non-composite desktop view directly into the first PanelWorkspace.

   public void ShowViewByName(string name, IViewInfoReader info)
   {
      UnloadCurrentCompositeView();

      _viewContainer = _workspaceContainer.CreateInnerContainer();
      CompositeView view =
         _viewContainer.ResolveByName<CompositeView>(name);
      // this will end up in some code checks and a call to "OnShow"
      Show(view, info);
   }

Since the composite view is not a real view, we do not display it, but rather use its typed properties to load the appropriate sub-views. All the subviews are created within the shared _viewContainer. As result, if some sub-views require shared controller/manager (ICalendarSyncController, for example) in their constructors, then the first view will create that controller and the subsequent views will hook up to the existing instance.

   protected override void OnShow(CompositeView view,
      IViewInfoReader viewInformation)
   {
      view.LoadInfo(viewInformation);
      CompositeViewParameters parameters = view.Parameters;

      if (parameters.Count != _workspaces.Length)
         throw new InvalidOperationException();

      for (int i = 0; i < _workspaces.Length; i++)
      {
         _workspaces[i].SetContext(_viewContainer);
         _workspaces[i].ShowViewByName(parameters.ViewNames[i],
            parameters.ViewInfos[i]);
      }

      Activate(view);
   }

Notes:

  • The shared controllers/managers have to be registered in IoC as container-owned singleton instances.
  • if the composite workspace allows opening and closing of sub views, everything will keep on working. If new view being opened needs some shared controller/manager to sync with or subscribe to, then it will pull it from the constructor (thus automatically hooking to the over views). The drawback is that all shared controllers/managers will be disposed only when the workspace closes the entire composite view.

It is quite easy to add on-the-fly configuration of the composite view by the end-users. User could have XtraLayoutControl (or its analogue) to customize the layout. When he is done with the customization, the workspace is reinitialized with the set of panels that were created within the LayoutControl (PanelWorkspace is created out of each one); then the CompositeViewParameters object is simply assembled based on the actual items that the user has dropped there. The assembled information is passed to the Composite workspace (and optionally persisted in the appropriate IDataNode). IoC and DI will settle down the rest.

I didn’t realize you could do that.

PS: One could find more information on workspaces and UI composition while reading the sources for the Microsoft Composite Application Block. Plus there’s always list of posts on xLim 2 architecture.