Home>

Here I say a few more words,When everyone is studying,Such as reading books or watching videos,Because it feels almost understandable and easy.Actually understanding is one thing,It's one thing you can do it yourself,Being able to speak for yourself is another matter.You should turn what you have learned into your own,Rather than drawing scoops like that.

Before talking about reflection,Let's first understand what is an assembly?

Assembly

The assembly is.concept in net,An assembly can be thought of as wrapping a bunch of related classes,Equivalent to the jar package in java.

The assembly contains:

resource Type metadata (describes each type and member defined in the code,(Binary form) il code (these are all encapsulated in exe or dll)

The difference between exe and dll.

exe can run,dll cannot run directly,Because exe has a main function (entry function).

This type of metadata can be customized through the assemblyinfo.cs file.In every one.There is an assemblyinfo.cs file in the net project, the code format is:

using system.reflection;
using system.runtime.compilerservices;
using system.runtime.interopservices;
//General information about the assembly goes through the following
//Feature set control.
Changing these characteristic values ​​can be modified
//Information associated with the assembly.
[assembly:assemblytitle ("reflecteddemo")]
[assembly:assemblydescription ("")]
[assembly:assemblyconfiguration ("")]
[assembly:assemblycompany ("")]
[assembly:assemblyproduct ("reflecteddemo")]
[assembly:assemblycopyright ("copyright©2017")]
[assembly:assemblytrademark ("")]
[assembly:assemblyculture ("")]
//Set comvisible to false to make types in this assembly
//Not visible to the com component.
 If you need to access the types in this assembly from com,//set the comvisible attribute on the type to true.
[assembly:comvisible (false)]
//If this item is exposed to com, the following guid is used for the id of the type library
[assembly:guid ("7674d229-9929-4ec8-b543-4d05c6500863")]
//The assembly version information consists of the following four values:
//
//major version
//minor version
//generation number
//  Amendment No
//
//can specify all these values,You can also use the default values ​​for Build Number and Revision Number,//method is to use "*" as follows:
//[assembly:assemblyversion ("1.0. *")]
[assembly:assemblyversion ("1.0.0.0")]
[assembly:assemblyfileversion ("1.0.0.0")]

Where is this information reflected?Reflected in the properties of our assembly

When we usually install some cs client programs,You will see many assembly files under the installation directory.

Benefits of using assemblies

The program only references the necessary assemblies,Reduce the size of the program. An assembly can encapsulate some code,Provide only necessary access interfaces. Easy to expand.

How do I add a reference to an assembly?

Add assembly paths directly or add project references in the solution.

When we need to extend a program,You may add directly to the original project,Then that way,What if i want to share this code with others?You can package it into an assembly,Then others can just extend it by referencing your assembly.Like we are common.net third-party framework library,Such as log4net, unity, and so on.

Note:You cannot add circular references

What is adding circular references?That is to say, if the project reference of project b is added,Then at this time, the project reference of project a cannot be added to project b.In other words, when adding a project reference,Must be one-way,Like project references between our common three-tier frameworks.

reflection

Regarding reflection,You just have to do it.net development, you must use it every day.Because the intelligent prompt of vs is realized by applying reflection technology,There is also our commonly used decompiler artifact, reflector.exe. Just look at its name.More common in projects,Is to dynamically instantiate objects by combining configuration files,If you switch database instances,Or sprint.net's configuration file to achieve dependency injection and so on.

Reflection technology is actually the function of dynamically obtaining assembly metadata,Reflection works by dynamically loading a dll and then parsing it,To create objects,Call member.

type is a description of the class,The type class is an important class that implements reflection.Through it we can get all the information in the class,Including methods, properties, etc. You can call class properties and methods dynamically.

The appearance of reflection has changed the way objects are created,Because in the past, creating objects is done directly through new.

There are two parts in the dll:il intermediate language and metadata element.

The namespace used for reflection in .net is system.reflection. Here I first look at what reflection can do through a demo.

1. New console project reflecteddemo

2.New class library project my.sqlserver.dal

Create two new classes sqlserverhelper and sqlcmd. The former is a common class.The latter is a private class

namespace my.sqlserver.dal
{
  public class sqlserverhelper
  {
    private int age=16;
    public string name {get;set;}
    public string query ()
    {
      return string.empty;
    }
  }
  class sqlcmd
  {
  }
}

3. Project reflecteddemo, add project reference of my.sqlserver.dal,The purpose of my doing this is to facilitate the existence of the my.sqlserver.dal.dll assembly in the bin directory of the project reflecteddemo.

using system;
using system.reflection;
namespace reflecteddemo
{
  class program
  {
    static void main (string [] args)
    {
      //Load the assembly file,Find in bin directory
      assembly assembly=assembly.load ("my.sqlserver.dal");
      console.writeline ("---------------- modules ----------------------");
      var modules=assembly.getmodules ();
      foreach (var module in modules)
      {
        console.writeline (module.name);
      }
      console.writeline ("---------------- types ----------------------");
      var types=assembly.gettypes ();//Get all types in the assembly,Including public and private
      foreach (var type in types)
      {
        console.writeline (type.name);
        console.writeline (type.fullname);
        var members=type.getmembers ();//Get all public members in type
        console.writeline ("---------------- members ----------------------");
        foreach (var m in members)
        {
          console.writeline (m.name);
        }
      }
      console.writeline ("---------------- getexportedtypes ----------------------");
      var exportedtypes=assembly.getexportedtypes ();//Get all public types in the assembly
      foreach (var t in exportedtypes)
      {
        console.writeline (t.name);
      }
      console.writeline ("---------------- gettype ----------------------");
      var typename=assembly.gettype ("sqlserverhelper");//Get the type object with the specified name in the assembly
      console.writeline (typename.name);
    }
  }
}

Create objects dynamically

Via ass.createinstance (string typename) and activator.createinstance (type t) methods

The difference between them

ass.createinstance (string typename) will dynamically call the class's parameterless constructor to create an object,The return value is the created object,If there is no parameterless constructor, an error will be reported.

assembly assembly=assembly.load ("my.sqlserver.dal");
object obj=assembly.createinstance ("my.sqlserver.dal.sqlserverhelper");
console.writeline (obj.gettype (). tostring ());

If we modify the code of the sqlserverhelper class,Add the following constructor:

   public sqlserverhelper (int age)
    {
      this.age=age;
    }

At this time, running the code to create an instance will report an error.No errors are reported during compilation.

So we generally recommend using the activator.createinstance method to create reflection objects,Because this method has many overloads,Support for passing parameters to constructors.

At this point, no further exception will occur.

There are three more commonly used methods in the type class:

bool isassignablefrom (type t):Whether it can be assigned from t, to determine whether the current type variable can accept the assignment of t type variable. bool isinstanceoftype (object o):determine whether object o is an instance of the current class,The current class can be o's class, parent class, interface bool issubclassof (type t):determine whether the current class is a subclass of t

There is also an isabstract attribute in the type class:determine whether it is abstract,Contains interfaces.

The reason they are commonly used is that we can get too much through reflection.We need to filter the data.

Add class basesql, let class sqlserverhelper inherit from basesql

Then look at the calling code:

     bool result=typeof (basesql) .isassignablefrom (typeof (sqlserverhelper));
      console.writeline (result);
  sqlserverhelper _sqlserverhelper=new sqlserverhelper (1);
   bool result=typeof (sqlserverhelper) .isinstanceoftype (_sqlserverhelper);
   console.writeline (result);
     sqlserverhelper _sqlserverhelper=new sqlserverhelper (1);
      bool result=typeof (sqlserverhelper) .issubclassof (typeof (basesql));
      console.writeline (result);

Commonly used in projects to dynamically switch database demos:

Create a new class library project my.sql.idal, and add the interface isqlhelper. Decoupling classes for database operations through interfaces,Because the interface is abstract.

 public interface isqlhelper
  {
    string query ();
  }

Add class library project my.mysql.dal and add class mysqlhelper.cs

My.sqlserver.dal and my.mysql.dal projects add references to the project my.sql.idal respectively. Let sqlserverhelper inherit from interface isqlhelper

public class mysqlhelper:isqlhelper
  {
    public string query ()
    {
       return this.gettype (). tostring ();
    }
  }
  public class sqlserverhelper:isqlhelper
  {
    private int age=16;
    public string name {get;set;}
    public string query ()
    {
      return this.gettype (). tostring ();
    }
  }

Add app.config configuration item

<appsettings>
  <add key="dbname" value="my.sqlserver.dal, sqlserverhelper" />
 </appsettings>

program.cs calling code in reflecteddemo project:

string str=configurationmanager.appsettings ["dbname"];
      string strassembly=str.split (",") [0];
      string strclass=str.split (",") [1];
      assembly assembly=assembly.load (strassembly);
      type t=assembly.gettype (strassembly + "." + strclass);
      isqlhelper obj=activator.createinstance (t) as isqlhelper;
      console.writeline (obj.query ());

So every time you need to switch databases,Just modify the configuration file.

Project structure:

Note:Although reflection is very powerful,But it is more performance-intensive,So it is generally used in combination with caching.

Project source code:reflecteddemo.zip

c
  • Previous C # most complete method for uploading pictures
  • Next C # web application debugging open access steps analysis