In this post I want to talk about a common need that we could have in an applications, that is an object factory.
Of course, we could have different requirements about the implementation of it, but the most widespread is a generic factory like this:
public class ObjectsFactory { public object Create<TClass>() where TClass : class, new() { return new TClass(); } }
This is a very simple implementation, but with the new keyword we have a precondition, the generic object must have a public constructor and we wont be able to pass a class without it.
What we can do with the classes that have non public constructors, such as classes that have an internal access modifier to the constructor, that is exposed only to the relative assembly?
We have to implement another method in the factory for these classes.
Creating objects with non public constructor
This is the implementation of the new method:
..... public object CreateWithNonPublicConstructor<TClass>() where TClass: class { var constructor = typeof(TClass).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null); return constructor != null ? constructor.Invoke(null) : null; } .....
The first thing to observe is that the new keyword is removed, in order to allow the classes without a public constructor.
Then, with the GetConstructor method we search the constructor; this method has four parameters:
- BindingFlags, we search for non public and instance constructors
- Binder, in our case null
- Types, the parameters of the constructor, in our case a parameterless constructor
- Parameter modifiers of the constructor, we have no parameters so we haven’t modifiers
In the last row, if it has been finded, the constructor is invoked.
Test
Now we can test the factory; in this example we have two classes, Car with a public constructor and Person without it.
We implement two test methods like this:
[TestFixture()] public class ObjectsFactoryTest { [Test] public void TheObjectsWithConstructorAreGeneratedCorrectly() { var factory = new ObjectsFactory(); var car = factory.Create<Car>(); Assert.True(car != null); } [Test] public void TheObjectsWithNoConstructorAreGeneratedCorrectly() { var factory = new ObjectsFactory(); var person = factory.CreateConstructorLessObjects<Person>(); Assert.True(person != null); } }
That’s all, the factory exposes two different methods for classes with and without constructors and the user can choose based on the object that he needs to create.
Leave a Reply