Categories
C# .NET Managed Extensibility Framework

Dynamic DataContractSerializer KnownTypes with MEF

Have you ever used the .NET DataContractSerializer? Do you need to serialize types defined at runtime? Well then keep reading. There might be a simple solution to your problem. There are several ways of providing type information to the serializer.

The first method is the type provided to the serializer’s constructor. A second method is through a configuration file. This is particularly useful in the context of using Windows Communication Foundation (WCF) services particularly with third-party components. A third method is providing type information through the serializer’s KnownTypes property. This example is a variation on the last approach. The standard way of providing some known type information looks like this.

var serializer = new DataContractSerializer(typeof(TypeOne), new List<Type>(new[] { typeof(TypeTwo), typeof(TypeThree) });)

This standard approach provides a collection of known types when constructing the serializer. This works in many cases but what if you don’t know the types at design time? How about if they are defined in an assembly that is not referenced? The configuration file approach could solve this problem. What if you are using the serializer outside of WCF? Fortunately there is a simple solution. The Managed Extensibility Framework (MEF) comes to the rescue.

MEF facilitates loose coupling and runtime discovery of components. It warrants a post of its own but here is a high-level overview. MEF utilizes a CompositionContainer to expose exported types. Types are imported either through a constructor decorated with an [ImportingConstructor] attribute or members decorated with an [Import] attribute.

First I create an interface with a single collection property to store one or more types.

public interface IPersistable { IEnumerable<Type> Types { get; } }

Next I implemented the interface in the class I wanted to serialize.

[Export(typeof(IPersistable))] [DataContract] public class Order : IPersistable { [DataMember] public int Id { get; set; } [DataMember] public string ItemName { get; set; } [DataMember] public decimal Price { get; set; } public IEnumerable<Type> Types { get { return new[] { typeof(Order) }; } } public override string ToString() { return string.Format("Order - ID:{0} Item:{1} Price:${2}", Id, ItemName, Price); } }

Alternately a class that implements the interface and provides a collection of multiple types can be used. Either approach works fine. The last step is for the class that uses the serializer to import the type collections by using the [ImportMany] attribute.

public class DataPersistence { private readonly DataContractSerializer _serializer; [ImportingConstructor] public DataPersistence([ImportMany] IEnumerable<IPersistable> knownTypes) { if (knownTypes == null) throw new ArgumentNullException("knownTypes"); var types = knownTypes.SelectMany(t => t.Types); _serializer = new DataContractSerializer(typeof(object), types); } }

This is a simple way to dynamically provide type information to the DataContractSerializer. You can download the complete sample here.

Categories
C# .NET

C# Generic Object Factory

I recently was searching for some ideas for creating an object factory to centralize the creation of various class instances. I came across several interesting articles on the topic related to C# and .NET development. One in particular on The Code Project site caught my attention. I would like to thank Rob Hemstede for his Generic Object Factory article which was my inspiration for this post.

This one was my initial inspiration for this post  but they all lacked one thing. They were specific to individual types or families of objects.

One way of implementing a generic object factory in .NET is to use the Activator class. This can be accomplished with something like the following:

var type = Type.GetType("Namespace.Class, Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); var instance = Activator.CreateInstance(type);

I worked with this approach on a previous .NET 2.0 WinForms project. It leveraged the User Interface Process (UIP) Application Block from Microsoft’s Patterns and Practices site. The UIP block instantiated the views using a model-view-controller (MVC) pattern. This worked well and was robust. Although with this object factory I did not have the requirement of defining customized views at runtime through configuration. With that in mind I decided to take another approach in the design.

One thing I noticed with the various .NET examples I found was that each factory was specific to a single type or family of types. I wanted something that could be used to create various types of objects. In the past I had accomplished this type of functionality in C++ using function pointers. This approach led me to the following ObjectFactory class.

public class ObjectFactory { private SortedList<string, object> _factories = new SortedList<string, object>(); public void RegisterFactory<TR>(Func<TR> factory) { Add<TR>(factory); } public void RegisterFactory<T1, TR>(Func<T1, TR> factory) { Add<TR>(factory); } private void Add<TR>(object factory) { if (!_factories.ContainsKey(typeof(TR).FullName)) _factories.Add(typeof(TR).FullName, factory); } public TR Create<TR>() where TR : new() { return new TR(); } public TR Create<T1, TR>(T1 t1) { object factory; if (_factories.TryGetValue(typeof(TR).FullName, out factory)) ((Func<T1, TR>)factory).Invoke(t1); return default(TR); } }

Here is a simple example that demonstrates the usage of the ObjectFactory.

class Program { static void Main(string[] args) { var factories = new ObjectFactory(); factories.RegisterFactory<int, ITestObject>(id => new TestObject(id)); var testObj = factories.Create<int, ITestObject>(1); Console.WriteLine(@"ITestObject instance created with Id=" + testObj.Id); Console.ReadLine(); } }