Tag Archive for 'XPO' Page 2 of 3



How to use ORM (XPO), IoC, C# 3.5 syntax, Linq and .NET 2.0 together?

One of the most important features of any proper development architecture, environment or process, is that the synergy (network) effects accumulate, if you keep doing the right things. IoC/DI, unit testing and TDD, continuous integration - all these just form up the external side of how everything works. They simply help (or force) to shape the logics of the development to make everything fold smoothly and let your solutions accumulate the benefits.

Now, let us get back to the IoC+ORM series and take one more look at the ICommand implementation from the last post. It could be improved quite a bit:

public sealed class DisableAllAccounts : ICommand
{
  private readonly IRepository<Account> _accounts;
  private readonly ILog _log;

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

  public void Execute()
  {
    _log.Write("Disabling accounts:");
    _accounts.CriteriaString = "Disabled=0";
    foreach (var account in _accounts)
    {
      _log.Write(account.Name);
      account.Disabled = true;
      account.Save();
    }
  }
}

Things become better as we throw out things that do not fit well. So let us remove our custom IRepository<> from this picture (along with the FireCollection behind it) and get rid of the string literal in favor of something that is compiler-checked

Continue reading ‘How to use ORM (XPO), IoC, C# 3.5 syntax, Linq and .NET 2.0 together?’

How to inject ORM with some IoC?

This post continues ORM+IoC series, namely - the discussion initiated by “How to decouple your code from ORM (XPO) while granting it the power to IoC?” and comments that followed.

Let us try to inject ORM itself with some IoC and see what happens. Take a look at the following exaggerated command example:

public sealed class CreateRandomAccount : ICommand
{
  private readonly Account _account;
  private readonly ILog _log;

  public CreateRandomAccount(Account account, ILog log)
  {
    _account = account;
    _log = log;
  }

  public void Execute()
  {
    _log.Write("Creating new random account");
    _account.Name = Guid.NewGuid().ToString();
    _account.Disabled = true;
    _account.Save();
  }
}

I like to use some ICommand implementations as examples since they help to crystallize the effects of IoC in one single piece.

The code above, being resolved in some container, just does what it says: it asks for the class (registered as Factory instance) and saves it to some repository. IoC uses Session from the current scope to create the instance and so it will use UoW, session in transaction or whatever session descendant is available in the container. Additionally it writes a note to the logger.

Continue reading ‘How to inject ORM with some IoC?’

How to decouple your code from ORM (XPO) while granting it the power to IoC?

It is Sunday and there is too much work to do, but Nicholas Blumhardt has just got me totally distracted with his latest post on Enabling Rich Domain Models with Services. Comments by Jeremy Gray have just added to that.

So, it seems that in addition to ruling the IoC coupling out of the component code (while keeping its resolution powers in) we can simply rule out the entire ORM out of the code as well (in my case DevExpress eXpress Persistent Objects go for the ORM, but there is no big difference).

Take a look at the code below:

public sealed class ApproveTask : ICommand
{
  private readonly Session _session;

  public ApproveTask(Session session)
  {
    _session = session;
  }

  public void Execute()
  {
    var entries = new XPCollection<AccountEntry>(_session,
      CriteriaOperator.Parse("Approved=0"));
    foreach (var entry in entries)
    {
      entry.Approved = true;
    }
    _session.Save(entries);
  }
}

The code has some strong coupling with the XPO ORM, does not it? Now, what if we were to rewrite it like this:

public sealed class ApproveTask : ICommand
{
  private readonly IRepositoryFactory<IAccount> _repository;

  public ApproveTask(IRepositoryFactory<IAccount> repository)
  {
    _repository = repository;
  }

  public void Execute()
  {
    var filtered = _repository.GetFiltered("Approved=0");
    foreach(var account in filtered)
    {
      account.Approved = true;
    }
    _repository.Save(filtered);
  }
}

Now that feels to be much better in terms of re-usability and testability.

To implement that we just need to:

  1. Decouple our business objects from the ORM via the interfaces (if they are strongly coupled like it is done in XPO, where they have to inherit from the base class)
  2. write a generic IRepositoryFactory implementation for the XPO ORM that simply creates the wrapper for the XPCollection or XPServerCollection
  3. register the factory with the container scope to make it operate in the context of the Session or UnitOfWork of the current scope

Bonuses:

  • I use the string-based criteria in these code examples, but chances are that it would be possible to write server-side Linq statements instead.
  • Since the IRepository is the “IoC front” code, we can hand it the powers to IoC as well. For example, the domain objects might want to have that ILog interface or some IHashProvider. We can pass these down to the repositoryFactory same way it has been done with the IResolver: use “Action<T> injectProperties” that gets called after the domain object is retrieved by ORM (these will still have the current Session/Transation since they are resolved in the current scope). Additionally, since the IRepository implements “T Create()” member, we can present components with new objects that are already DI’d with the container.

But it gets more complicated if some business object holds a collection of aggregated objects as well…

Running xLim with latest Mono: XPO, autofac and binary compatibility

This is the update to the previous R&D post on running xLim (XPO+Autofac) under Mono 1.2.6.

Short summary:

  • Latest autofac code passes all tests with the latest mono sources
  • The dictionary issue (the one that required patching XPO sources) is fixed in the latest mono code
  • Binary remoting does not work for XPO purposes.

The reason for the last problem is simple: Mono and .NET implementations of the DateTime object are completely different. Serialized Mono DateTime uses more bytes than .NET implementation. The first one does not implement ISerializable, while the last one - does. That could make some difference.

Miguel de Icaza has pointed to the topic in Mono FAQ on the subject of binary compatibility between .NET and Mono. It turns out that the DateTime is not one of these compatible types. I wonder if there are other incompatible primitives or widely-used classes.

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.

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 run XPO in hosting environment with some CAS restrictions?

Here’s the small code snippet on enabling/disabling some XPO features depending on the hosting environment. Just plug it in your kernel initialization routine and you should be fine.

try
{
   new ReflectionPermission( ReflectionPermissionFlag.ReflectionEmit).Demand();
   new SecurityPermission( SecurityPermissionFlag.ControlEvidence).Demand();
}
catch (SecurityException)
{
   XpoDefault.UseFastAccessors = false;
}

Update: If you use data caching, then you might need to manually set the XPO cache size for your DataCacheNode instances (otherwise XPO will attempt to detect it automatically via the code that cannot run under the Medium Trust). Here’s the sample code snippet:

if (manualCacheSizeMb > 0)
{
   node.TotalMemoryPurgeTreshhold = 0;
   node.TotalMemoryNotPurgeTreshhold = manualCacheSizeMb*1024*1024;
}

So far these are the only CAS-related problems that were encountered while deploying current xLim 2 implementation (Server+WebUI) on the CrystalTech accounts.