Released Catel 3.7

We are very proud to announce the release of Catel 3.7. This release took us a very long time to create and did not follow our 2-monthly release schedule. This was due to the complete rewrite of the serialization engine which needed to be tested very thoroughly. Let’s dive into the new features and most important changes.

New serialization engine

The flagship of this release is the new serialization engine. In the older versions of Catel, the serialization logic of the ModelBase classes was fully written in the ModelBase itself. It was hard to modify this serialization logic or to customize the behavior. In this release the logic is now completely separated into custom classes which allow full customization of what gets serialized in what way. The big plus is that we didn’t have to modify the public API for this.

By default, the new engine will serialize all Catel-style properties. However it is possible to include any property or field in the serialization as well by simply decorating it with the IncludeInSerialization attribute. To exclude a Catel property from serialization, you can now decorate it with the ExcluseFromSerialization attribute.

Another cool feature in the new serialization engine is the ability to create Serialization Modifiers. These are small classes which allow you to fully customize what gets serialized for a specific model. Below is an example which encrypts the password of a model before actually serializing it:

public class PersonSerializerModifier : SerializerModifierBase<Person>
{
	public override void SerializeMember(ISerializationContext context, MemberValue memberValue)
	{
		if (string.Equals(property.Name, "Password"))
		{
			memberValue.Value = EncryptionHelper.Encrypt(memberValue.Value);
		}
	}

	public override void DeserializeMember(ISerializationContext context, MemberValue memberValue)
	{
		if (string.Equals(property.Name, "Password"))
		{
			memberValue.Value = EncryptionHelper.Decrypt(memberValue.Value);
		}
	}
}

The only thing required to register it is to decorate your model class:

[SerializerModifier(typeof(PersonSerializerModifier))]
public class Person : ModelBase
{
	// .. class contents
}

IoC changes

There are several major improvements for the Inversion of Control (IoC) in Catel.

Introduction of the DependencyResolver

Instead of having to use the full-blown ServiceLocator to resolve the types, we have now implemented a light-weight DependencyResolver which wraps the ServiceLocator. The advantage is that this resolver is now scope-aware and will use the right ServiceLocator and TypeFactory which was used to create the type that uses the DependencyResolver. This means that if you create object x with a custom ServiceLocator (and thus custom TypeFactory), resolving the DependencyResolver will use the right scope.

To get the right IDependencyResolver or ITypeFactory, use the following extension methods:

var dependencyResolver = this.GetDependencyResolver();
var typeFactory = this.GetTypeFactory();

The advantage is that we are one step closer to allow full customization of the IoC technologies being used in Catel. For example if one would prefer Unity, AutoFac or Ninject, that will be possible in the future (we have planned this for 3.8).

Dependency injection support in nested view models

The TypeFactory now supports creating types where some parameters are customized and the other parameters of a constructor are automatically completed by resolving the types from the DependencyResolver. This allowed us to implement a feature request that was highly on our list: dependency injection support in nested view models with model injection. This feature allows to write the following constructors on nested user control view models:

public MyViewModel(MyModel model, IService1 service1, IService2 service2)
{
    // left out for this example
}

New extensions

In Catel 3.7, two new extensions are introduced:

Interception

Interception Extensions enables you to write code that is executed each time a matching method is invoked using a fluent API. It’s suited for cross cutting concerns, such as transactions, security and logging. For more information about interception, take a look at the official documentation.

DynamicObjects

In .NET, it is possible to create fully dynamic objects. This makes it possible to create types of which the members are not yet known at compile time. Starting with Catel 3.7, the DynamicModelBase is fully dynamic and still provides the features such as serialization. Catel supports dynamic objects by implementing the IDynamicMetaObjectProvider which is available in WPF, Silverlight and Windows RT.

The cool thing about the support for Dynamic Objects support in Catel is that it fully supports serialization. This means that you can define dynamic objects on the fly which can be serialized at any time.

Support for Portable Class Libraries

Starting with version 3.7, Catel.Core will be supported by the Portable Class Libraries. We do not have plans to convert the MVVM because the PCL is too limited to do so. If you want Catel.MVVM on a specific platform, just reference the right NuGet package (because we do support all target platforms).

More information

This release has over 90 changes. Check out the full release notes at our issue tracker.