Tag Archive for 'IoC' Page 2 of 3



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…

How to avoid tight IoC coupling in non-deterministic resolution scenarios?

Normally IoC should never go into the code below the level of module/component registration. That’s the rule.

But what if some specific component needs to resolve components based on some conditions (i.e. resolving by name when name is passed externally)?

You can use dictionary if the components are singletons, but this would not work if they have to be resolved in the current scope. For example, we might need to execute some workflow class knowing only its name and interface. And some workflow class (neither we know, nor do we care) could just need to access the data store within the scope of the current session.

These simple interface declarations help me to manage scenarios like this with a couple of lines of code, while keeping the IoC intrusion minimal:

public interface IResolver<Param, Object>
{
  Object Resolve(Param param);
}

public interface IResolver<Object> : IResolver<string, Object> { }

Additionally there is a simple class to lend IoC to the components with inlining:

public class Resolver<Param, Object> : IResolver<Param, Object>
{
  private readonly Func<Param, Object> _function;

  public Resolver(Func<Param, Object> function)
  {
    _function = function;
  }

  public Object Resolve(Param param)
  {
    return _function(param);
  }
}

public sealed class Resolver<Object> :
  Resolver<string, Object>, IResolver<Object>
{
  public Resolver(Func<string, Object> function) : base(function)
  {
  }
}

With that you can register named resolution of some interface (ICommand, for example) with this nice statement:

builder.Register(scope => new Resolver<ICommand>(
  name => scope.ResolveByName<ICommand>(name)))
  .As<IResolver<ICommand>>()
  .WithScope(InstanceScope.Container);

and then it could be later used in any component like

public sealed class TaskExecutor
{
  private readonly Resolver<ICommand> _commands;
  public TaskExecutor(Resolver<ICommand> commands)
  {
    _commands = commands;
  }

  ...
  _commands.Resolve(commandName).Execute();
  ...
}

Remarks:

  • The resolution interfaces should always be explicitly written. That’s just to keep the code under control.
  • This function-based resolver interface simplifies unit testing quite a bit (especially if you use MockContainer).
  • Do not try this code at home with your IoC container unless this container is Autofac.
  • Using some global static class (i.e.: IoC.ResolveByName…) is not a valid solution either, because:
    • That’s global static class and its usage just complicates code management and testing
    • Static resolution would not have any clue about the current scope (rendering it useless)

Why do not we resolve delegates in IoC?

Do you see the difference between these two declarations of some imaginary command?

public sealed class DeleteCommand : ICommand
{
  private readonly IRecordSelector _recordSelector;
  private readonly IMessageBoxService _messaging;
  private readonly IRecordManager _recordManager;

  public DeleteCommand(IRecordSelector recordSelector,
    IMessageBoxService messaging, IRecordManager recordManager)
  {
    _recordSelector = recordSelector;
    _messaging = messaging;
    _recordManager = recordManager;
  }

  public void Execute()
  {
    List<XPObject> records;
    if (_recordSelector.TryGetOneOrMoreRecords(out records))
    {
      if (_messaging.Ask("Do you really want to delete '{0}' records?",
        records.Count))
      {
        _recordManager.Remove(records);
        _recordSelector.RefreshData();
      }
    }
  }
}

and this one

Action<IRecordSelector, IMessageBoxService, IRecordManager> command =
  (selector, messaging, manager) =>
{
  List<XPObject> records;
  if (selector.TryGetOneOrMoreRecords(out records))
  {
    if (messaging.Ask("Do you really want to delete '{0}' records?",
      records.Count))
    {
      manager.Remove(records);
      selector.RefreshData();
    }
  }
};

Class version is longer but it can be resolved in IoC. The delegate is more concise but it does not resolve.

So, why do not we resolve delegates in IoCs?

PS: additional difference is that if command is stateless then it could be resolved only once in the IoC scope and the subsequent executions will use “cached” version (Container scope instead of Factory could be used). But I’d trade that for the DRY principle.

xLim 2 Engine concept or simple continuous integration for businesses

xLim 2 Engine is an extremely simple concept and continues the idea from post on “How to simplify complex maintenance tasks of your information management solution?“.

So, if you have architecture like this, you can just:

  • take multiple maintenance and automation tools of yours
  • throw out all the repetitive code (connection, logging, security, etc) and wrap everything that remains with some common interface (ICommand or Action<IContainer> are equally fit here)
  • Create some simple host (Win Service, Mono daemon, Console Application) that establishes an IoC environment by loading the shared assemblies (by just asking the shared module to register), then resolves every command in a dedicated scope and runs it.

Since the commands are just ordinary IoC components, you can configure them in some XML file and provide the parameters. The resulting config file will resemble NAnt build file quite a bit. The only difference is that you are playing with business objects, workflows and services instead of some low-level development entities.

And since the engine talks to the main server via the common gateway interface (and uses some access account for this), you can be sure that

  • all possible harm will be limited by the permissions defined by the account
  • logging and audits will be applied

We recently had to implement similar automation engine for the current xLim 2 implementation. That was extremely easy with this concept, since all we had to write was the engine host (200LOC for the console implementation) and the actual command logic. Shared modules lent us all the other required functionality (and even a couple of ICommand implementations were reusable)

Now, you’ve just got your simple business integration engine. Adding new tasks is trivial here, since you have to worry only about the actual code (the engine and IoC will DI all the required interfaces from the shared modules). Given that, you can easily:

  • Send warning if some system goes short on DB or HD space
  • Save sales numbers every 1 hour to capture the statistics for future analysis
  • Fire alarms if some KPIs go out of range
  • Send message to admin if that document processor service is not responding again
  • Alert developers if there are any exceptions in the server log

It is an interesting coincidence that Ayende had written about the continuous validation concept in his web log. That fits quite close in this picture, although I believe he mixes two different concepts that logically should be separated: Environment Validation Framework and the Automation Engine.

Basically, the validation framework is just some IValidationReporter interface that is supported by some singleton components living in the root scopes of the application being validated. And then there is some component that generates composite validation report per request and sends it to the external monitoring system.

Now, why do we want to separate environment validation from the engine? These are the reasons:

  • System might not have the components/interfaces for running regularl environment validation checks and then taking some actions based on complex logic (do you want to add that extra code in there just for that?)
  • Configurations of different systems might have different ways of going invalid (i.e.: some systems could have recommended HD limit of 40Mbs while others could be limited to 40GBs, some could require access to dedicated workflow server and some could just live without that). You would not to spread that info with every config.
  • Some failures could be detected only after being aggregated (i.e. work cluster could be considered to be in invalid state if all nodes are consistently overloaded)
  • Some failures could be linked to external systems (i.e. HD space allocation for the user depends on type of the account of his company)

So it seems to be more efficient to have dedicated automation engines (you could have as many of them as you want) to handle all the meta-system logic, while leaving only report generation to the actual system being monitored.

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.

Managing xLim 2 flexibility: IoC Container Inspector

In the last post I’ve blogged about the schema manager application for the xLim 2 approach for building flexible solutions. We go on from here.

Schema Manager encapsulates three different ideas:

  • Container Inspector
  • Configuration Manager
  • Validation Test Runner

These three pieces are logically linked to each other, and because of that there’s the synergy effect. It makes the resulting combination even more efficient and easy to implement.

Let’s talk about the container inspector bit for a while.

IoC Container Inspector UI for the xLim manager

The idea of the container inspector comes from the StructureMapExplorer and the CAB visualizer. Both had helped me a lot in understanding and visualizing what exactly happens within the multi-scoped applications (and why does this happen).

In this solution the container inspector is responsible for retrieving and displaying the information about the “Loaded Modules” sub-tree. It is implemented for the autofac as a simple ContainerInterceptor class that allows us to capture all the calls to the container with IComponentRegistration data. Then, we simply take all modules to be loaded and run them against this container interceptor one by one. And then we just take note of every registration that takes place (just 100 lines of code to do that).

Note, that the interceptor has to forward the calls to the real container, since modules are actually loaded in this virtual environment. And within the load process it is a common thing for some extension module to registers item in the service provided by the core module (or augment it).

Additionally the Container Inspector allows us to run one more validation check on the composite schema, just to make sure that the components and services that are referenced there actually exist. This is useful for the cases where modules do not create their schema bits on-the-fly, but rather preload existing schema bit from the resources. Of course the SchemaManager would detect the broken links and throw exceptions, but who wants to debug the logics when you can see only one error at a time? That’s simply inefficient.

With a little bit of imagination one can make the Container Inspector more powerful than this by:

  • Providing short descriptions for the modules and services via the attributes (usable when the modules are distributed to the other developers)
  • Grouping all named implementations by the supporting interface(s) (it is not needed within xLim 2, since the composite schema handles this in a flexible way)
  • Running validation tests for the components that support this (we’ll get to that later)
  • Exploring the properties of any given module, letting you to configure them and creating *.config file for the loaded modules.
  • Linking the upper container to NMock2 (we’ll talk about the MockContainer approach a bit later) attempting to resolve any given component (that’s one of the reasons not to put any scope-specific logic into the constructor), reporting all container dependencies for the component including these that are not satisfied by the root application scope (that’s the scope the modules get loaded into).

The last item would probably be helpful for xLim quite soon since a lot of modules do that kind of trick:

  • Register scope-specific items that use some new service
  • Register that new service in the root application scope.

Now, what happens, when the scoped item get resolved within some child scope? It pulls that service right from upper scope and would fail if it is not there. That’s the logical dependency. If the service is registered within the same module with the scoped component, then it is easy to remember and manage. But if the service is registered within one module (i.e.: IExtensionWorkflow32 from Extension.Core) and then other components depend on it (i.e.: ExtensionDesktopView from Extension.Client and ExtensionWebView from Extension.Web), then we’d better to explicitly visualize these dependencies (and optionally auto generate the module documentation for that).

Imagine, if the Model Editor for the DevExpress eXpressApp Framework (XAF) supported this bit of functionality. Wouldn’t it make the task of writing and managing the extension modules just a little bit easier?

PS: Next posts within autofac and xLim 2 series could be on MockContainer implementation or on the problems of running xLim server under Mono. We’ll see how the research and development goes.

Managing the flexibility

Basically the capabilities of any given xLim 2.0 application are defined by the modules that have been loaded. Modules, when they are loaded, can do all sorts of complex things with .NET code:

  • Register business objects.
  • Register new components with different scopes, ownership, registration procedures (lambda, factory, reflection, instance etc)
  • Resolve components registered by other modules and augment them.

We do not care about the specifics as long as the IoC takes care of the registration/resolution and the modules do not break the system.

However, in order to configure the application, we need to know what building-blocks do we get after some modules get loaded (including all the modules they depend on).

This can be simply done by loading the desired assemblies into the IoC and then examining the actual results:

xLim Schema Manager

Additionally the modules can optionally provide some configuration presets for their components. These presets are merged into a single composite schema (basically just a class that is registered in the IoC by the SharedCoreModule that contains all the common functionality) and are also trivial to inspect and validate.

xLim Schema Manager

While we are at the schema level, we can also create our own configuration bits and save them to the configuration file for the specific application host.

Additionally, since the container has been actually loaded, we can check out how ViewSchemas would actually look when loaded by the desktop detail/grid views, or how command links would merge together into Ribbon/Bars in different combinations. Basic validation testing also happens here.

The third level of the configuration is creation of the actual navigation tree. It would reference the configured handlers (optionally overriding some parameters) to build the UI for the Web/Desktop users. This piece is done by the small console client, that connects to the running xLim server as the root user and builds the tree.

Users from the SuperAdmin group normally get the desktop view to modify the existing tree on-the-fly, but it is rarely used and kept only for the situations where it is urgently needed to reconfigure the production system (i.e.: allow manager to edit some fields, disable the workflow rules for some customer, add commands to the menu of the low-level user etc).

PS: the next post describes IoC Container Inspector functionality (logic behind the “Loaded Modules” bit) in detail.