Subscribing to change notifications without memory leaks

by Geert 1. March 2013 22:11

You know this feeling? You are doing the best you can to prevent memory leaks by correctly unsubscribing from all events, and then you hit that object from which you cannot determine the lifetime. Well, you have a few options:

  1. Don’t talk about it, maybe your app won’t be used that much so maybe nobody notices.
  2. Try to implement IDisposable, but when to call that, you don’t know the end of life of the object?
  3. Fix the issue, but how?!

Note that this solution works on .NET, Silverlight, Windows Phone and WinRT. It doesn’t matter whether you use ASP.NET MVC, MVVM in WPF of your own custom pattern.

How do I create a memory leak?

Creating a memory leak is very easy. Simply subscribing to change notifications of objects mostly results in large statements such as the one below:

   1:  var itemAsPropertyChanged = obj as INotifyPropertyChanged;
   2:  if (itemAsPropertyChanged != null)
   3:  {
   4:      itemAsPropertyChanged.PropertyChanged += OnPropertyChanged;
   5:  }

 

What is the solution to prevent memory leaks?

You can either use the WeakEventListener in Catel or use the brand new ChangeNotificationWrapper that is now available in the latest prerelease version of Catel on NuGet. The ChangeNotificationWrapper allows the subscription of both the INotifyPropertyChanged and INotifyCollectionChanged interfaces using weak events, thus preventing memory leaks.

Subscribing to events of an observable object

Using the code below, one can subscribe to the PropertyChanged event of an object:

   1:  var wrapper = new ChangeNotificationWrapper(obj);
   2:  wrapper.PropertyChanged += OnPropertyChanged;

Note that it is not required to check whether the object implements INotifyPropertyChanged, the wrapper does it automatically

Subscribing to events of an observable collection

Using the code below, one can subscribe to the CollectionChanged event of an object:

   1:  var wrapper = new ChangeNotificationWrapper(observableCollection);
   2:  wrapper.CollectionChanged += OnCollectionChanged;

Note that it is not required to check whether the object implements INotifyCollectionChanged, the wrapper does it automatically

Advanced scenario with observable collections

Sometimes it is required to watch both changes inside a collection, but also the items inside a collection. For example, there is a list of customers and you are also interested in changes of customers inside a collection. This is fully supported by the ChangeNotificationWrapper using the code below:

   1:  var wrapper = new ChangeNotificationWrapper(observableCustomerCollection);
   2:  wrapper.CollectionChanged += OnCollectionChanged;
   3:  wrapper.CollectionItemPropertyChanged += OnCollectionItemPropertyChanged;

All subscriptions are automatically managed by the ChangeNotificationWrapper when items are added or removed from the collection.

Unsubscribing from events

When you are no longer interested in events from the source object, there are two options:

  1. Just leave them coming, as soon as the objects are no longer used, they will be garbage collected
  2. Unsubscribe using the following code:
   1:  wrapper.UnsubscribeFromAllEvents();


Grabbing the bits

As always, Catel is open-source thus you can either check out the source or grab the latest bits via NuGet.

Tags: , ,

C# | Catel

Entity Framework Unit of Work and repositories

by Geert 27. February 2013 20:11

Catel is an application development platform for C# that was primarily focused on xaml languages (WPF, Silverlight, Windows Phone). The core however is usable by server implementations as well and more and more extensions are being developed. This blog post will give an introduction to the Unit of Work and the repositories that are available in Catel.

Overview of Unit of Work and repositories

The Repository and Unit of Work (UoW) pattern are very useful patterns to create an abstraction level over the DbContext that is provided by Entity Framework. A much heard excuse not to use repositories is that EF itself already works with repositories (the DbContext) and a UoW (in the SaveChanges method). Below are a few examples why it is a good thing to create repositories:

  • Abstract away some of the more complex features of Entity Framework that the end-developer should not be bothered with
  • Hide the actual DbContext (make it internal) to prevent misuse
  • Keep security checks and saving and rollback in a single location
  • Force the use of the Specification pattern on queries

A Unit of Work (UoW) is a a combination of several actions that will be grouped into a transaction. This means that either all actions inside a UoW are committed or rolled back. The advantage of using a UoW is that multiple save actions to multiple repositories can be grouped as a unit.

A repository is a class or service responsible for providing objects and allowing end-developers to query data. Instead of querying the DbContext directly, the DbContext can be abstracted away to provide default queries and force required functionality to all end-developers of the DbContext.

A Unit of Work (UoW) is a a combination of several actions that will be grouped into a transaction. This means that either all actions inside a UoW are committed or rolled back. The advantage of using a UoW is that multiple save actions to multiple repositories can be grouped as a unit.

A repository is a class or service responsible for providing objects and allowing end-developers to query data. Instead of querying the DbContext directly, the DbContext can be abstracted away to provide default queries and force required functionality to all end-developers of the DbContext.

image

The image above shows that the Unit of Work is the top-level component to be used. Each UoW contains its own DbContext instance. The DbContext can either be injected or will be created on the fly. Then the UoW also contains repositories which always get the DbContext injected. This way, all repositories inside a UoW share the same DbContext.

The DbContextManager

The DbContextManager class allows the sharing of DbContext (with underlying ObjectContext) classes in Entity Framework 5. The good thing about this is that the same context can be used in the same scope without having to recreate the same type of the same context over and over again.

   1:  using (var dbContextManager = DbContextManager<MyEntities>.GetManager())
   2:  {
   3:      var dbContext = dbContextManager.DbContext;
   4:   
   5:      // TODO: handle logic with dbContext here
   6:  }
 

Creating a Unit of Work

A UoW can be created by simply instantiating it. The end-developer has the option to either inject the DbContext or let the DbContextManager take care of it automatically.

   1:  using (var uow = new UnitOfWork<MyDbContext>())
   2:  {
   3:      // get repositories and query away
   4:  }


Creating a repository

A repository can be created very easily by deriving from the EntityRepositoryBase class. Below is an example of a customer repository:

   1:  public class CustomerRepository : EntityRepositoryBase<Customer, int>, ICustomerRepository
   2:  {
   3:      public CustomerRepository(DbContext dbContext)
   4:          : base(dbContext)
   5:      {
   6:      }
   7:  }
   8:   
   9:  public interface ICustomerRepository : IEntityRepository<Customer, int>
  10:  {
  11:  }

 

Retrieving repositories from a Unit of Work

Once a UoW is created, it can be used to resolve repositories. To retrieve a repository from the UoW, the following conditions must be met:

  1. The container must be registered in the ServiceLocator as Transient type. If the repository is declared as non-transient, it will be instantiated as new instance anyway.
  2. The repository must have a constructor accepting a DbContext instance

To retrieve a new repository from the UoW, use the following code:

   1:  using (var uow = new UnitOfWork<MyDbContext>())
   2:  {
   3:      var customerRepository = uow.GetRepository<ICustomerRepository>();
   4:   
   5:      // all interaction with the customer repository is applied to the unit of work
   6:  }

 

Saving a Unit of Work

It is very important to save a Unit of Work. Once the Unit of Work gets out of scope (outside the using), all changes will be discarded if not explicitly saved.

   1:  using (var uow = new UnitOfWork<MyDbContext>())
   2:  {
   3:      var customerRepository = uow.GetRepository<ICustomerRepository>();
   4:   
   5:      // all interaction with the customer repository is applied to the unit of work
   6:   
   7:      uow.SaveChanges();
   8:  }

 

Getting the assemblies and/or code

You can either get the assemblies via NuGet or view the source on codeplex.

Tags: , , , , ,

Catel | C# | Entity Framework

Catel 3.4 is released!

by Geert 15. December 2012 16:43

It has been quite a while, but today a new version of Catel is released. It took us more time then usual, but in return we have a great version ready to be downloaded via the site or via NuGet.

Added WinRT and Windows Phone 8 support

This is probably the most noticeable “feature” of all. Both WinRT and Windows Phone 8 are fully supported with all features that you are familiar with in Catel. This means that we were able to port everything (not really everything, but 90 %) of it to WinRT and all known Windows Phone features to Windows Phone 8.

Performance improvements

For this release, we focused on performance. We made a lot of improvements by tracing and tweaking all the calls thoroughly. Below is a list of tweaks:

  • All reflection calls are now being cached
  • Logging is only executed when there are actually listeners registered
  • ModelBase.LeanAndMeanModel property to (temporarily) suspend both validation and change notifications, great when restoring models from disk
  • Added a FastObservableCollection which allows the adding of a range and only invokes a single event at the end
  • It is now possible to control (globally or per control) whether InfoBarMessageControl and WarningAndErrorValidator controls must be created or MVVM controls
  • Constructors in the ServiceLocator are cached which gives a major performance boost when creating new instances of types with dependency injection

Improved IoC container

The IoC container in Catel, the ServiceLocator, now supports registration of types with a tag. This allows the same type to be registered multiple times.

And much more…

Besides new features, we also fixed over 40 issues in this new release. Not all new features are described in this blog post, so make sure you get the latest version while it’s hot!

Tags:

MVVM | C# | Catel | Windows Phone 7 | Windows Phone 8 | WinRT | WPF | Silverlight

Catel 3.2 is released!

by Geert 8. July 2012 11:32

The Catel team is very proud the announce the new 3.2 release. As always, the new version is available via NuGet and via Codeplex (http://catel.codeplex.com).

In this blog post, I will try to explain the most important new changes in Catel.

Dependency injection support in the ServiceLocator

The ServiceLocator in Catel now fully supports dependency injection. This means that when a type is being resolved from the ServiceLocator.

Dependency injection via the ServiceLocator in Catel is enabled by default. This means that when a type is resolved from the container, it will automatically use dependency injection to construct the type if it is not registered as instance.

It will first search for all available constructors on the type that will be instantiated. Then, for each constructor, starting with the one with the most parameters, it will try to retrieve all values. If one fails, it will go to the next. If all fail, it will try to use the default constructor without parameters. If that fails as well, then the type cannot be constructed and an exception will be thrown.

To get a better understanding of what happens, see the class below:

public class MyClass
{
  private IFirstDependency _firstDependency;
  private ISecondDependency _secondDependency;
 
  public MyClass()
     : this(null) { }
 
  public MyClass(IFirstDependency firstDependency)
     : this(firstDependency, null) { }
 
  public MyClass(IFirstDependency firstDependency, ISecondDependency secondDepdenceny)
  {
    _firstDependency = firstDependency;
    _secondDependency = secondDependency;
  }
}

When the MyClass will be retrieved from the ServiceLocator, this will happen:

  1. Find constructor with most parameters (the one with both firstDependency and secondDependency). If both IFirstDependency and ISecondDependency can be resolved from the ServiceLocator, the type will be constructed with the constructor. Otherwise it will proceed with step 2.
  2. Find next constructor with most parameters (the one with only firstDependency). If IFirstDependency can be resolved from the ServiceLocator, the type will be constructed with the constructor. Otherwise it will proceed with step 3.
  3. At this point, no constructor could be used. In this case, the ServiceLocator will try to use the default constructor (the one without parameters) as last resort to instantiate the type.

Introducing the ViewModelFactory

In previous versions of Catel, it was only possible to inject a datacontext into a view model. In Catel 3.2, the new ViewModelFactory is introduced. This class is responsible for instantiating the view model.

By default, the implementation does exactly the same as before, but this gives great freedom when the view models cannot be instantiated by Catel itself (for example, when dependency injection is used, or when the registered view models of a control are interfaces).

Below is an example of a custom implementation of a view model factory:

public class CustomViewModelFactory : ViewModelFactory
{
  public override IViewModel CreateViewModel(Type viewModelType, object dataContext)
  {
      if (viewModelType == typeof(MySpecialViewModel))
      {
          // Use custom constructor with dependency injection
          return new MySpecialViewModel(dep1, dep2, dep3, dataContext);
      }
 
      // Fall back to default behavior
      return base.CreateViewModel(viewModelType, dataContext);
  }
}

All reflection is cached

In preparation for WinRT support, we moved all reflection to a single class with extension methods. This was a great opportunity to add caching to all reflection.

This means that all reflection is cached on the first call. This provides major performance improvements when using reflection.

More flexible behavior base classes

Catel already provided memory leak free base classes for behaviors and triggers. In the new version, a few new base classes are introduced to allow faster behavior developmentP:

  • CommandBehaviorBase – supports a command, command parameter and key modifiers out of the box
  • UpdateBindingBehaviorBase – supports binding updates on dynamic dependency properties

Core services now only use interfaces for MVVM integration

The core services (such as the MVVM behaviors) in Catel now use interfaces such as INotifyableViewModel and IRelationViewmodel. This makes it possible to use different base classes for view models and still use the full potential of Catel.

Updated to latest external libraries

We also took the time to update all external libraries to the latest version. The following libraries were updated:

  • Ninject (3.0)
  • Castle.Windsor (3.0)
  • FluentValidation (3.3.1)

Tags: ,

C# | Catel | MVVM | WPF | Windows Phone 7 | Silverlight

FlattenHierarchy for static members in WinRT

by Geert 2. July 2012 21:11

Recentely, I needed the same behavior of BindingFlags.FlattenHierarchy in WinRT that we are used to in .NET. At first, this didn’t work out because I was using the consumer preview, not the release preview.

In the release preview, Microsoft added great extensions methods as the RuntimeReflectionExtensions class. However, I was still facing issues where static base members were not returned by the extension methods. Below is an example of a unit test that will fail:

   1:  public class Foo 
   2:  { 
   3:      public static int StaticFooField; 
   4:  }
   5:   
   6:  public class Bar : Foo 
   7:  { 
   8:      public static int StaticBarField; 
   9:  }
  10:   
  11:  [TestClass]
  12:  public class ReflectionFacts
  13:  {
  14:      [TestMethod]
  15:      public void ReturnsAllStaticInheritedMembers()
  16:      {
  17:          var allItems = typeof(Bar).GetRuntimeFields().ToList();
  18:   
  19:          Assert.AreEqual(2, allItems.Count);
  20:      }
  21:  }

Where I would expect both fields to be returned, the GetRuntimeFields() method will only return all inherited non-static members. It does flatten the hierarchy for all non-static members though. However, I needed to achieve the same behavior as FlattenHierarchy | Static in my code.

I wrote lots of extension methods to achieve the same reflection code in both WinRT and .NET. Below shows how to walk down the stack to get the same behavior as FlattenHierarchy | Static:

   1:  /// <summary>
   2:  /// Gets the fields.
   3:  /// </summary>
   4:  /// <param name="typeInfo">The <see cref="TypeInfo"/>.</param>
   5:  /// <param name="bindingFlags">The binding flags.</param>
   6:  /// <returns>An array of <see cref="FieldInfo"/>.</returns>
   7:  /// <exception cref="ArgumentNullException">The <paramref name="typeInfo"/> is <c>null</c>.</exception>
   8:  public static FieldInfo[] GetFields(this TypeInfo typeInfo, BindingFlags bindingFlags)
   9:  {
  10:      Argument.IsNotNull("typeInfo", typeInfo);
  11:   
  12:      var flattenHierarchy = ShouldFlattenHierarchy(bindingFlags);
  13:      var source = flattenHierarchy ? typeInfo.AsType().GetRuntimeFields().ToList() : typeInfo.DeclaredFields.ToList();
  14:   
  15:      var includeStatics = Enum<BindingFlags>.Flags.IsFlagSet(bindingFlags, BindingFlags.Static);
  16:   
  17:      // TODO: This is a fix because static members are not included in FlattenHierarcy, remove when this is fixed in WinRT
  18:      if (flattenHierarchy)
  19:      {
  20:          var baseType = typeInfo.BaseType;
  21:          if ((baseType != null) && (baseType != typeof(object)))
  22:          {
  23:              source.AddRange(from member in GetFields(baseType.GetTypeInfo(), bindingFlags)
  24:                              where member.IsStatic
  25:                              select member);
  26:          }
  27:      }
  28:   
  29:      if (!includeStatics)
  30:      {
  31:          source = (from x in source
  32:                      where !x.IsStatic
  33:                      select x).ToList();
  34:      }
  35:   
  36:      return (from x in source
  37:              where x.IsStatic == includeStatics
  38:              select x).ToArray();
  39:  }

If you are interested in more reflection extensions, see this file.

WinRT is quite cool when you get it all working out Smile

Tags: , ,

Catel | WinRT


About the Author

Geert van Horrik is an independent freelance software developer since January 1st, 2007. Since then he was been working on several projects from C++ to C# (WPF, Silverlight, ASP.NET, etc). Currently he loves to write his software using WPF (or Silverlight if WPF isn't an option).

Lately, Geert is spending a lot of time on Catel, a free open-source MVVM Framework for WPF and Silverlight. Actually, it's more than "just" an MVVM Framework, it's a complete application library!