Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

Alternative ways to instantiate objects

4.76/5 (12 votes)
1 May 2012CPOL4 min read 40.1K   266  
Introduction for beginners on how to dynamically instantiate external types

Introduction 

In the vast majority of times when we are coding an application, we use the keyword "new" to instantiate an object, as shown below:
VB.NET
Dim obj As New AnyObject
In this article we will see two other ways on how to <code>dynamically instantiate objects without using the keyword "new".  

Background  

In a project that I recently participated one of the requirements was to instantiate objects dynamically based System.Types external to the application. 

It was a UserControl whose purpose was to display in a PropertyGrid properties of the instantiated object so that only the properties modified by the user in the PropertyGrid, were persisted and subsequently reapplied to the object whenever a new instance of it was created. 

The System.Type to be loaded was provided by the user by informing the assembly location on disk and the System.Type to instantiate

During the tests phase, I've used other assemblies created by me in other projects and also assemblies created by others to make sure it was actually working properly regardless of the class.

During this period, I found some situations in which the instantiation via reflection would not work. 

Instantiating through reflection 

 This type of instantiation is widely used by most programmers who need to dynamically create instances of System.Type 's external to the application.

By using Assembly.CreateInstance(string) to instantiate a type all the instantiation process occurs normally as if you were using the keyword "new", that is the constructor of the class is executed and all its fields gets initialized properly. 

VB.NET
Dim obj1 As Object = _assembly.CreateInstance("MyExternalAssembly.AnyObject"

In the example above we are instantiating a class called "AnyObject" on the assembly called "MyExternalAssembly". 

In this case you must provide a string with the full name of the System.Type including the assembly name and namespace (if any), and the name of the class also it must exist in the _assembly object, otherwise the instantiation does not occur.

Note: Internally after check if the provided System.Type string exists in the loaded assembly, it runs the Activator.CreateInstance(<span>System.Type)</span> method that returns the instance to the caller. 

Instantiating through Serialization/Deserialization  

I decided tocall this kind of instantiation as "serialization / deserialization" due to the fact that its being used internally in the .Net Framework to deserialize WCF DataContracts.

For a few times during the testing phase in the project I participated in, I came across situations where logic in the constructor of the class were preventing the instantiation of the object, especially when it was a commercial component whose licensing mechanisms were located in the constructors of the class and were firing  exceptions when licensing rules were violated. 

Note: In my opinion a good mechanism for licensing and validation must rely not only on the constructor of a class, but also in key methods of the class, and other classes internal to it. 

In cases like this instantiating a class by using Reflection is not possible since via Reflection and also  through the keyword "new", the constructor always runs during instantiation, preventing it from complete. 

By analyzing the .Net framework code through Reflector, I found that the WCF's DataContracts when deserializing an object were never invoking any class's constructors, as well as their fields were not initialized with "default" values that eventually were defined on it. 

The reason why the fields are not initialized makes sense. From what I understand is a way to gain performance, since during deserialization - after object creation - these fields will receive different values other than the "Defaults", that way it doesn't make any sense if they were assigned twice, once with their "defaultvalues ??and another with the values ??of serialization. 

I still do not understand why the constructor is not invoked, perhaps for performance reasons as well? I do not know ... 

Below is the code that does the instantiation without running the constructors or initializing fields:  

VB.NET
Dim type = _assembly.GetType("MyExternalAssembly.OtherObject")
Dim obj1 As Object = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type) 


Note that the method GetUninitializedObject() takes a System.Type that can be a System.Type from an existing class in the assembly itself or an external assembly, however the external assembly should be previously loaded. 

In the example above we use a System.Type from an assembly external to the application, whose constructor throws an InvalidOperationException, therefore we can never instantiate an object of this class if we use the standard instantiation by using the keyword "new" or a instantiation via Reflection  

Using the source code 

In the solution of the source code of this article there are two projects, a Class Library and a Windows Form Application. 

The "MyExternalAssembly" is a Class Library which has two classes, one is a class called "AnyObject" that allows any instantiation mentioned in this article to be used, the other class is called "otherObject" which is a class whose default constructor fires one exception, therefore it can be instantiated only by using the process "serialization/deserialization" presented here. 

The Project PropertyInspector is a Windows Forms Application that allows you to select an external assembly - in this case the assembly MyExternalAssembly - and display your fields in a PropertyGrid, as follows: 

 

 

Summary 

The purpose of this article is to show to beginners alternative ways to instantiate objects and not neither to elect the best way to instantiate an object nor the one that is "more correct"

Perhaps there are other ways to instantiate objects in .NET I may not know yet, if you do, please, feel free to share it with us by using the session "Comments and Discussions". 

Depending on usage, one method may be more advantageous than the other in terms of gains in performance, usability, etc.  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)