top button
Flag Notify
    Connect to us
      Facebook Login
      Site Registration Why to Join

    Get Free Article Updates

Facebook Login
Site Registration

Introduction To .NET Assemblies

0 votes
57 views

Introduction

You must have heard the word assembly many times in .NET documentation. In this article I will share some thing about .NET assemblies.

What is an assembly?

  • An Assembly is a  logical unit of code
  • Assembly physically exist as DLLs or EXEs
  • One assembly can contain one or more files
  • The constituent files can include any file types like image files, text files etc. along with DLLs or EXEs
  • When you compile your source code by default the exe/dll generated is actually an assembly
  • Unless your code is bundled as assembly it can not be used in any other application
  • When you talk about version of a component you are actually talking about version of the assembly to which the component belongs.
  • Every assembly file contains information about itself. This information is called as Assembly Manifest.

What is assembly manifest?

  • Assembly manifest is a data structure which stores information about an assembly
  • This information is stored within the assembly file (DLL/EXE) itself
  • The information includes version information, list of constituent files etc.

What is private and shared assembly?

The assembly which is used only by a single application is called as private assembly. Suppose you created a DLL which encapsulates your business logic. This DLL will be used by your client application only and not by any other application. In order to run the application properly your DLL must reside in the same folder in which the client application is installed. Thus the assembly is private to your application.

Suppose that you are creating a general purpose DLL which provides functionality which will be used by variety of applications. Now, instead of each client application having its own copy of DLL you can place the DLL in 'global assembly cache'. Such assemblies are called as shared assemblies.

What is Global Assembly Cache?

Global assembly cache is nothing but a special disk folder where all the shared assemblies will be kept. It is located under <drive>:\WinNT\Assembly folder.

How assemblies avoid DLL Hell?

As stated earlier most of the assemblies are private. Hence each client application refers assemblies from its own installation folder. So, even though there are multiple versions of same assembly they will not conflict with each other. Consider following example :

  • You created assembly Assembly1
  • You also created a client application which uses Assembly1 say Client1
  • You installed the client in C:\MyApp1 and also placed Assembly1 in this folder
  • After some days you changed Assembly1
  • You now created another application Client2 which uses this changed Assembly1
  • You installed Client2 in C:\MyApp2 and also placed changed Assembly1 in this folder
  • Since both the clients are referring to their own versions of Assembly1 everything goes on smoothly

Now consider the case when you develop assembly that is shared one. In this case it is important to know how assemblies are versioned. All assemblies has a version number in the form:

major.minor.build.revision

If you change the original assembly the changed version will be considered compatible with existing one if the major and minor versions of both the assemblies match.

When the client application requests assembly the requested version number is matched against available versions and the version matching major and minor version numbers and having most latest build and revision number are supplied.

How do I create shared assemblies?

Following steps are involved in creating shared assemblies :

  • Create your DLL/EXE source code
  • Generate unique assembly name using SN utility
  • Sign your DLL/EXE with the private key by modifying AssemblyInfo file
  • Compile your DLL/EXE
  • Place the resultant DLL/EXE in global assembly cache using AL utility

How do I create unique assembly name?

Microsoft now uses a public-private key pair to uniquely identify an assembly. These keys are generated using a utility called SN.exe (SN stands for shared name). The most common syntax of is :

sn -k mykeyfile.key

Where k represents that we want to generate a key and the file name followed is the file in which the keys will be stored.

How do I sign my DLL/EXE?

Before placing the assembly into shared cache you need to sign it using the keys we just generated. You mention the signing information in a special file called AssemblyInfo. Open the file from VS.NET solution explorer and change it to include following lines :

[assembly:AssemblyKeyFile("file_path")]

Now recompile the project and the assembly will be signed for you.

Note : You can also supply the key file information during command line compilation via /a.keyfile switch.

How do I place the assembly in shared cache?

Microsoft has provided a utility called AL.exe to actually place your assembly in shared cache.

AL /i:my_dll.dll

Now your dll will be placed at proper location by the utility.

Hands On...

Now, that we have understood the basics of assemblies let us apply our knowledge by developing a simple shared assembly.

In this example we will create a VB.NET component called SampleGAC ( GAC stands for Global Assembly Cache). We will also create a key file named sample.key. We will sign our component with this key file and place it in Global Assembly Cache.

  • Step 1 : Creating our sample component

Here is the code for the component. It just includes one method which returns a string.

imports system 

namespace BAJComponents 
	public class Sample
		public function GetData() as string 
			return "hello world" 
		end function 
	end class 
end namespace 
  • Step 2 : Generate a key file

To generate the key file issue following command at command prompt.

sn -k sample.key

This will generate the key file in the same folder

  • Step 3 : Sign your component with the key

Now, wee will sign the assembly with the key file we just created.

vbc sampleGAC.vb /t:library /a.keyfile:sample.key
  • Step 4 : Host the signed assembly in Global Assembly Cache

We will use AL utility to place the assembly in Global Assembly Cache.

AL /i:sampleGAC.dll

After hosting  the assembly just go to WINNT\Assembly folder and you will find your assembly listed there. Note how the assembly folder is treated differently that normal folders.

  • Step 5 : Test that our assembly works

Now, we will create a sample client application which uses our shared assembly. Just create a sample code as listed below :

imports system 
imports BAJComponents 
public class SampleTest 
	shared sub main() 
		dim x as new sample 
		dim s as string=x.getdata() 
		console.writeline(s) 
	end sub 
end class 

Compile above code using :

vbc sampletest.vb /t:exe /r:<assembly_dll_path_here>

Now, copy the resulting EXE in any other folder and run it. It will display "Hello World" indicating that it is using our shared assembly.

posted Dec 29, 2016 by Shivaranjini

  Promote This Article
Facebook Share Button Twitter Share Button LinkedIn Share Button


Related Articles

Introduction

Reflection is ability to find information about types contained in an assembly at run time. Prior to .NET languages like C++ provided such ability in a limited sense. .NET provides a whole new set of APIs to introspect assemblies and objects. All the APIs related to reflection are located under System.Reflection namespace. .NET reflection is a powerful mechanism which not only allows you to inspect type information but also allows you to invoke methods on those types at runtime. Certain reflection APIs also allow creating of assembly in memory dynamically and use it in your code. In this article we will examine the basic and most commonly used features of reflection. Reflection APIs can be used to develop applications like class browsers, add-ons for development IDEs and inelegant editors.

.NET assemblies

Assemblies are the building blocks of any .NET application. All functionality of .NET application is exposed via assemblies. Assemblies form a unit of deployment and versioning. Assemblies contain modules which in turn contain various types (classes, structures, enumerations etc.).

Getting started

The first thing you should do while using reflection classes is to include System.Reflection namespace.

using System.Reflection;

Loading an assembly

Before obtaining any information about types contained in an assembly we must first load the assembly.

Assembly myassembly = Assembly.LoadFrom("employee.dll");

This statement loads an assembly called employee.dll. You can substitute your own path here. Assembly class has a static method called LoadFrom that loads the specified assembly in memory. The method returns an instance of assembly class itself.

obtaining details about types from the assembly

The next step is to obtain a list of various types contained in the assembly.

Types mytypes[] = myassembly.GetTypes();
Type mytype=myassembly.GetType("Company.Employee");

There are two methods to get type information . The method GetTypes returns an array of System.Type objects. The method GetType returns a type object having details of specified object. Note that in our example Company is the namespace. In case your assembly do not contain any namespace you will simply write the type name.

Obtaining type details

The Type class has following properties that gives details about the type under consideration :

  • Name : Gives name of the type
  • FullName : Give fully qualified name of the type
  • Namespace : Gives namespace name
  • IsClass
  • IsInterface
  • IsAbstract
  • IsCOMObject : Indicates if the type is a COM object
  • IsEnum
  • IsSealed
  • IsPublic

All the property names are self-explanatory and need no separate explanation.

obtaining details about methods, properties and fields

Each type may have fields (member variables), properties and methods. The details about each of these types are obtained by following methods of the Type object.

  • GetMembers() : Gives array of MemberInfo objects
  • GetFields() : Gives array of FieldInfo objects
  • GetProperties() : Gives array of PropertyInfo objects
  • GetMethods() : Gives array of MethodInfo objects

Note that you can also get information about specific method, property or field using GetMethod("mymethod"), GetProperty("myprop") or GetField("myfield") methods.

MethodInfo[] mymethods= mytype.GetMethods();
MethodInfo mymethod = mytype.GetMethod("GetSalary");

Following paragraphs list commonly used properties and methods of above objects. The property and method names are self explanatory. You can refer MSDN for more details.

Properties and methods of MethodInfo Object

  • Name
  • IsPrivate
  • IsPublic
  • IsStatic
  • IsConstructor
  • ReturnType
  • GetParameters()
  • Invoke()

Properties and methods of PropertyInfo Object

  • Name
  • CanRead
  • CanWrite
  • PropertyType
  • GetValue()
  • SetValue()

Properties and methods of FieldInfo Object

  • Name
  • FieldType
  • IsPublic
  • IsPrivate
  • IsStatic
  • GetValue()
  • SetValue()

Invoking a method on a type

We have seen how to get information about various types from an assembly. Reflection also allows us to create instances of these types and invoke methods on them. Following code fragment shows just that.

Assembly a=Assembly.LoadFrom("employee.dll"); 
Type t=a.GetType("Company.Employee"); 
MethodInfo getsalary=t.GetMethod("DisplayMsg"); 
object obj=Activator.CreateInstance(t); 
object[] p=new object[1]; 
p[0]="Hello bipin"; 
getsalary.Invoke(obj,p); 
Assembly a=Assembly.LoadFrom("employee.dll"); 
Type t=a.GetType("Company.Employee"); 
MethodInfo getsalary=t.GetMethod("GetSalary"); 
object obj=Activator.CreateInstance(t); 
object[] p=new object[1]; 
p[0]="bipin"; 
object retval=getsalary.Invoke(obj,BindingFlags.DefaultBinding,
                               null,p,null); 
Console.WriteLine(retval);

Here, we first obtained type of employee class. We then created an instance of it using Activator.CreateInstance() method.  There are two forms of Invoke() method :

  • If your method is not returning any value then you may use following form
    Invoke ( obj , obj[])
  • If your method is returning some value and you want to trap it use following form :
    obj = Invoke ( obj , bindingflag, binder , parameters, cultureflag )

For both the forms you pass instance of object on which the method will be called and array of objects that contains method parameters.

The second method shown here is with most commonly used values for BindingFlags, Binder and Culture. For more detailed information on the second syntax of Invoke method please refer MSDN.

Summary

Reflection allows a powerful mechanism to introspect your types. The reflection APIs can be found in System.Reflection namespace. The APIs allow you to inspect types as well as create types on the fly and invoke methods on them.

 

READ MORE

What are Win Forms?

In earlier versions of VB and other Visual Studio products there were different 'Forms' engines. So forms developed using VB were different than other languages. With Visual Studio.NET the picture has changed. Now, all the tools supporting NGWS make use of a common forms engine. The forms thus created are called as Win Forms. This leads to many benefits (also refer VS.NET documentation for more details):

  • Common look and feel
  • Added functionality ( Yes! VB forms can now have scrollbars!)
  • Significantly reduces control-container interoperability issues.
  • Win Forms takes full advantage of the security features of the NGWS runtime.
  • Win Forms offers support to Web Services.
  • Win Forms provides rich graphics with the help of GDI+, a new version of the Windows Graphical Device Interface
  • Win Forms offers a rich set of controls
  • Win Forms offers full support for the ADO+ data model.
  • Win Forms offers support for ActiveX controls.
  • Win Forms takes advantage of the NGWS Runtime enhanced licensing model.
  • Win Forms offers a printing framework that enables applications to provide comprehensive reports.

First WinForms application

Now, let us create a simple form which will just display "Hello Win Forms" This is very simple example but illustrates general structure of VB.NET classes for displaying forms.

 

   Imports System
   Imports System.WinForms

   Namespace Bipin.Samples

       Public Class HelloWinForms
       Inherits System.WinForms.Form

           Shared Sub Main()
               Application.Run(New HelloWinForms())
           End Sub

           Public Sub New()
               MyBase.New
               Me.Text = "Hello Win Forms"
           End Sub

       End Class

   End Namespace

Note the following points :

  • We have imported namespaces called System and Systems.WinForms. The later contains all the controls (like label, button etc) we will be using next.
  • We declared our own namespace called Bipin.Samples
  • The namespace contains a class called HelloWinForms which is inherited from Form class
  • In VB.NET constructors are represented by a method named New(). This method calls constructor of the base class (mybase.New) and sets title of the form to "Hello Win Forms"
  • An instance of the form is created in Shared (which is nothing but Static in C++/Java) method called Main()

Compiling the application

You can compile the application using command line compiler vbc

 

vbc file_name /r:System.WinForms.dll /r:System.Drawing.dll

Here, file name is the name of source file i.e. xxxx.vb. The switch /r points namespaces [r]eferenced in the application.

Adding Controls to the Form

Now, we will see how to add controls to the form

 

   Imports System
   Imports System.WinForms
   Imports System.Drawing

   Namespace Bipin.Samples

       Public Class HelloWinForms
       Inherits System.WinForms.Form

			Dim label1 as new label

           Shared Sub Main()
               Application.Run(New HelloWinForms())
           End Sub

           Public Sub New()
               MyBase.New
               Me.Text = "Hello Win Forms"
               label1.text="Hello Win Forms"
               label1.location=new point(100,100)
               me.controls.add(label1)
           End Sub

       End Class

   End Namespace
  

 

  • We have created an instance of label class called label1
  • The newly created label is added to the form in the constructor using me.add method of the form
  • Then we set some properties like location and text of the control. Note that point class is present in System.Drawing namespace, hence we import it.
  • Also, note that you can set properties of the control at any time - before adding to the form as well as after adding to the form

Event handling

Now, let us proceed further and see how to handle events of the controls.

 

   Imports System
   Imports System.WinForms
   Imports System.Drawing

   Namespace Bipin.Samples

       Public Class HelloWinForms
       Inherits System.WinForms.Form

		   Dim button1 as new Button

           Shared Sub Main()
               Application.Run(New HelloWinForms())
           End Sub

           Public Sub New()
               MyBase.New
               Me.Text = "Hello WinForms"
               button1.text="Click Me"
               button1.location=new point(100,100)
               button1.addonclick(addressof button_click)
               me.controls.add(button1)
           End Sub

           public sub button_click
           (sender as object,evt as eventargs)
	           	Messagebox.show("Hello Win Forms")
           end sub

       End Class

   End Namespace
  

This example is similar to previous one but uses a command button. When user clicks on the button a message box will be displayed saying "Hello Win Forms" Here is how we handled click event of the button :

  • To indicate that you want to handle certain event you must register a sub or function with that event (Java people will find themselves at home!)
  • This is done using AddOnxxxxx (source as object, evt as eventargs) syntax where xxxxx represents the event name (Click in our case)
  • This method also requires address of the function/sub which handles the event (button_click in our case)
  • The event handling must match syntax shown i.e first argument of type object and second of type eventargs. In some cases (like mouse events) extra information is passed to the event handler via this second argument
  • Note that now you can use same function to handle events from multiple controls
  • We have displayed message box using NGWS Messagebox.show() method. If you want to use old VB methods/functions you need to import Microsoft.VisualBasic in your application

I hope you must have got overall idea about win forms. The next articles of this series will cover techniques like creating menus and using other controls. So, visit soon!

READ MORE
Contact Us
+91 9880187415
sales@queryhome.net
support@queryhome.net
#280, 3rd floor, 5th Main
6th Sector, HSR Layout
Bangalore-560102
Karnataka INDIA.
QUERY HOME
...