Tag Archive for 'XPO'

Implementing ORM-independent Linq queries

We’ll get back from the Boo + Business + DSL to the XPO + ORM + IOC series for a little bit.

Nicholas Blumhardt has just written an interesting and extremely thorough article on Implementing the Specification Pattern via Linq. Let’s try to play with the idea and take it a one step down the road. Here we can:

1. Add ORM abstraction by implementing generic IRepository (of T) interface:

public interface IRepository<T>
{
	IQueryable<T> Find(QueryFor<T> query);
	IQueryable<T> Find(string criteria);
	IQueryable<T> Find<K>() where K : QueryFor<T>, new();
	IQueryable<T> Query();

	// ...
}

Continue reading ‘Implementing ORM-independent Linq queries’

XPO hosted on a web site (remoting with binary encoding + http channel)

Below you will find an extremely simple prototype that uses XPO hosted within web application (http channel) with the binary encoding. You will need to have DevExpress components installed and Visual Studio 2008.

Now, before you continue, here is an important caveat - don’t use XPO in any complex project. It will just become bottle-neck there.

In my case complex project means:

  • 41 Visual Studio projects (74k LOC and 35k statements)
  • 3 integration projects on CC.NET
  • 417 revisions over 6 months
  • 2Gb+ FileStore in production system
  • All the features of the xLim 2 approach (and some more)

Here’s the Kiviat metrics graph:

xLim 2-2 Kiviat Graph

And these are some of the problems with the XPO:

  • Linq2XPO implementation is horrible (I’m not even talking about decent documentation)
  • Flexibility is extremely low (most of all I miss custom mapping routines and ability to specify custom queries)
  • Generated SQL is quite inefficient in complex requests
  • Remote communication is too chatty by default

As you can see, these problems of mine mostly come from the Lego scenario.

If I were able to start the project from scratch, then I’d probably (would have to do some prototyping first) use NHibernate. Half a year ago there was no chance of using it, since DX controls would not be able to work with NHibernate in server mode.

Ok, you have been warned. Now you finally can download sample of XPO hosted on a web site (remoting with binary encoding + http channel).

Some notes on XPO and continuous validation testing

I’m really “deep in the trenches” right now due to two concurrent projects running. Nonetheless, here are just some quick notes:

  • Avoid using DevExpress XPO for large-scale projects where the future requirements could change. It is extremely easy to get started with that, but in the long term your DAL could become a bottleneck in the process of the project evolution (flexibility is too limited).
  • Do not use XPO 2 Linq! It supports only basic queries and has absolutely no documentation/matrix/test suite to validate and tell what’s working and what is not. Test suite of NHibernate 2 Linq is something I would expect to find in such a product.
  • There is another option for the single gateway interface (as in DevExpress XPO) utilized by xLim projects. That’s the WCF 2 Linq project or any other analogue (there surely be more of these as the technology gets adopted).
  • Some say that the combination of Final Builder and TeamCity is the most flexible for the integration purposes. Well, this could be true - FB even has tasks to deal with VMs.

Inspired by the abovementioned NHibernate 2 Linq test suite (it utilizes the power of MBUnit) I recently implemented a nice business test suite for the xLim2-2 application. Basically this is the test suite that re-uses connectivity and logic modules implemented with the help of Autofac IoC container (simple config is used to get them setup and running). The initialization happens in the global setup routine (supported by MBUnit). And then the actual tests just resolve some components/services from the main container (every test is running within its own container scope) and run simple assertions around these.

Example of an assert could be - “make sure that there are no critical errors in the system log”, “make sure that loose object references in the database point to each other” or “make sure that file store is in consistent state with the DB”.

So, provided you have the proper config and the compiled unit test, you just can point it to any production system and check its status in simple manner.

If we take the idea further, then these tests could be uploaded to the CruiseControl.NET to let them run against production on a schedule. And if something breaks - you’ll get the notification immediately (CC.NET will handle that).

Additionally it is easy to set up continuous statistics capturing via the same tech. So we get continuous system validation here and continuous system monitoring at the expense of writing just some validation tests and doing one-time setups.

Red Gate and Seeding problems

Red Gate tools are the best for the database management routines (update schema, update data etc).

  • Red Gate 2
  • Red Gate 3
  • Red Gate 1

However they are not flawless (version 6) as I thought before. For some reason after a number of syncs identity seed got messed up in a couple of tables. Fortunately this has been one of the development databases. To fix the issue I had to resort to writing queries by hand:

declare @P1 int
set @P1 = (select max (Oid) from FormValue_Date)
DBCC CHECKIDENT(FormValue_Date, RESEED, @p1)

So, if you using DevExpress XPO and suddenly start getting “Violation of PRIMARY KEY constraint ‘PK_Name’. Cannot insert duplicate key in object ‘Name’”, do not rush to the Support Center. Check identity information first with:

DBCC CHECKIDENT(TableName)

From Web Services to IIS-hosted remoting: XPO performance improvement.

Switching from “XPO over Web Service” to “XPO over IIS hosted remoting” made select operations 20% faster for the average usage scenario in xLim. Adding Forms Authentication on top of the remoting didn’t have any significant impact.

Note, that in this test scenario the remote server was located on the ASP.NET Intermediate shared hosting plan in CrystalTech data center. Desktop Smart Client was located on the opposite side of the Earth. If we remove the distance factor (ping between these two points is 245ms on the average), then the speed improvement for this scenario is 26%.

No optimization to the HttpChannel code has been done. Although, probably bringing over the compression logics from WCF would yield better performance results (at the cost of CPU load).

Update: sample can be downloaded here.

XPO-related changes that are needed to make the ORM+IoC samples work.

Below you will find the description of the minimal changes to XPO sources to make the ORM+IoC series samples work. Obviously, I’m quite limited with that, since these sources are commercial.

That’s the new method that we have to add to ReflectionDictionary to make it recognize out interfaces:

public void AddClassInfo(Type service, XPClassInfo implementation)
{
  classesByType.Add(service, implementation);
}

Or one could just add method that looks up existing type registration and re-registers it as service type, while hiding the ClassInfo specifics.

The changes, that differ FireSession (and logically linked classes) from normal Session, revolve around the delivery of the _resolver delegate from the FireSession Constructor to this method inside ObjectLoader:

void CreateTypedObject(object id, XPClassInfo classInfo) {
  theObject = null == _resolver ?
    classInfo.CreateObject(loader.Session) :
    _resolver(classInfo.ClassType);
  cache.Add(classObjects, theObject, id);
}

The _resolver delegate is a simple lambda passed down from the IoC:

private Func<Type, object> _resolver;
...
// register FireSession with the default data layer
builder.Register<Session>(
  c => new FireSession(type => c.Resolve(type))).ContainerScoped();

Note: these 30min hacks are neither stable nor intended for production. It would require at least XPO unit-test suite and IoC+ORM functionality/integration tests to stabilize them with all the required usage scenarios. And that’s out of the scope of the current research.

In my next article I’ll get to the topic of the efficient unit-testing of decoupled components with the MockContainer. That’s where we left the xLim 2 series.

How to implement unit-testable abstraction and reusable domain models with IoC + ORM?

In the previous post in ORM+IoC series we’ve managed to decouple away from the ORM-based collection and the literal-based syntax (which was bound to the logics of eXpress Persistent Objects ORM).

In this post we’ll try to get rid of all the remaining coupling (while making it unit-testable) and even add domain-based extensibility that is easy to implement.

Let’s modify the code:

public sealed class DisableAllAccounts : ICommand
{
  private readonly IOrderedQueryable<IAccount> _accounts;
  private readonly ILog _log;

  public DisableAllAccounts(IOrderedQueryable<IAccount> accounts, ILog log)
  {
    _accounts = accounts;
    _log = log;
  }

  public void Execute()
  {
    _log.Write("Disabling accounts:");

    var accounts = from c in _accounts
                   where (c.Disabled == false)
                   select c;

    foreach (var account in accounts)
    {
      IComment comment = account.CreateComment();
      comment.Text = string.Format("Account {0} was disabled on {1}",
        account.FirstName, DateTime.Now);
      comment.Save();
      account.Disabled = true;
      account.Save();
    }
  }
}

Continue reading ‘How to implement unit-testable abstraction and reusable domain models with IoC + ORM?’