Summary: Custom attributes of .NET can implement program collective data extensions and provide new ideas and solutions for frame design and implementation. NUnit is a good example.
1. Property overview
The metadata system of .NET is one of the highlights of the .NET Framework. Using metadata, an assembly, module, type, method, member, etc. are used to describe, and these descriptions are compiled as metadata into the assembly and is used by the .NET operating environment. This is also the metadata extension.
The definition of attributes and use is the main content of metadata extension. This includes the use and custom properties of the .NET standard properties.
Note: "Properties" is the concept of Chinese MSDN to the concepts discussed in this article - I am used to saying this. This seems to be easier to confuse the "attribute" in OO. In some similar discussions, this translation is "label", "tag", please pay attention to distinguish.
Maybe developers also feel more unfamiliar with attributes, and there is no sense of sensibility to how they play a role. But actually in daily development, .NET developers have already used the standard properties of .NET. Such as:
When you want to reference a function in a traditional dynamic connection library, we often use the DLLIMPORTATTRIBUTE standard properties to comment the prototype of a function:
[DLLIMPORT ("User32.dll")] Public Static Extern Int MessageBoxa (int P, string m, string h, int t); // ...
For example, the WebServiceAttribute and WebMethodAttribute property are used when writing Web Service. [WebService] and [WebMethod] play a role when generating WSDL, generates the corresponding Web Service description, how familiar with the following code snippet developers:
[WebMethod] public string helloworld () // ...
These attributes commented directly to the type or type of members in the program, and such annotations can affect the compilation, logic, operation, etc. of the corresponding assembly. The .NET Framework has many standard properties and has a detailed document in the MSDN.
2. Custom attribute
Attributes can also be customized, namely, the property is developed, and the attribute is defined in a format, and the properties use attributes to affect the developer's own assembly. This is also the most direct application of .NET metadata extension. Custom attributes are compiled as metadata when compiling, and the reflection mechanism can be read when running.
The attribute in .NET is defined in the form of a class. Almost all attributes are inherited from System.attribute, and the developer custom properties need to first inherit from the abstraction class.
Custom attributes can be used to mark and describe elements in the assembly, and compiled into .NET assembly, become part of its metadata. The reading from the attribute and attribute value is the read of the .NET program collective data, which will be used to reflect mechanisms. How do you write a custom attribute and how to read the properties, there are many examples in the MSDN, and it is no longer redundled.
3. Application of attribute
The properties of the attribute are often useful when designing some frameworks: using reflex mechanisms, metadata as attributes can be reversed to run configuration items affecting code in the running period, or for special operation methods to mark in order to Do special treatment at runtime. Another tempting application of the property is that tools that can be used to build management project assemblies: property is characterized by some annotation, and the comment content can be read from the assembly after compiling, so that the property content can be Note and reads to implement various types and methods in the program center.
3.1 Attributes in NUNIT
Let's take a look at the app in the frame design! The most typical example is NUnit. The characteristics of the custom attribute, and the reflection mechanism of .NET are played in the frame design in NUnit. Take a simplified test case (TestCase) as an example: NUNIT needs to run three different functions as follows: first run the environment preparation function before running the test; then 0 ~ N test functions; It is the test environment cleaning function. Developers who are familiar with NUnit know that the [setup], [TEST], [TEARDOWN] attributes are used in NUNIT's TestCase. Such examples:
// A NUNIT test program set code [setup] public void init () // ... [teardown] public void destroy () // ... [test] public void testXXX () // ...
The NUnit Frameworks takes the above functions from the time of the test program to be tested, and the above three different functions are set in the correct order. NUNIT is this:
The first is to develop a set of properties to mark various functions in TestCase, such as: [Setup], [TEST], [TEARDOWN]. (NUnit's properties tags are not used to mark the functions in the program, but is limited to the space, here only in the previous simplified environment)
NUNIT uses the reflection mechanism to run the function in TestCase that has been compiled into an assembly at runtime. There is a series of functions in the NUnit framework to complete this job, which is only responsible for running the function tagged by the specified attribute tag in the test case program. Such as: invokeSetup () is responsible for running a function marked with [setup]; InvokeTestCase () is responsible for running a function of [TEST], the test case; InvokeTeardown () is responsible for running the [Teardown] function. Then NUnit uses the call of these invokexxxxxxx () functions to ensure the success of these three functions.
// from templatestcase in nUnit.core namespace {// ... try {// ... invokesetup (); first running the [setup] tag Function // ... InvokeTestCase (); // then [Test] // ...} catch (...) // ... finally {// ... invoketeardown (); // Finally [Teardown] tag function // ...} / / ...}
The invokexxx () function uses the reflective mechanism to run the relevant function, you can take a look at the following code segments:
// From TemplateTestCase in NUnit.Core namespaceprivate void InvokeSetUp () {MethodInfo method = FindSetUpMethod (fixture); // obtain [SetUp] Examples of markers reflecting function if (method = null!) {InvokeMethod (method, fixture); // Run the function}}
FindSetupMethod (...) By calling a function called FindMethodByattribute (...), the reflective mechanism is used to obtain MethodInfo that can call the function, and finally run through InvokeMethod (MethodInfo, ...).
// From Test class in NUnit.Core namespaceprotected void InvokeMethod (MethodInfo method, object fixture) {if (method = null!) {Try {method.Invoke (fixture, null); // call the method reflected by the method or configuration instance Function} catch (...) // ...}} Carefully read the source code can see that because NUNIT uses the reflex mechanism to run the test case in the test program, the return value of [setup], [TEST], [TEARDOWN] function, The parameters have specific requirements to form a rule coupling. This is the necessary design to facilitate reflection implementation, simplify the framework.
You can see the application of custom properties in the .NET metadata extension in the frame design, which believes that there will be more framework class items to utilize the characteristics of the .NET custom property. Here is the relationship between several classes involved in this article (a simplified).
3.2 Property Other Applications
Excellent architecture enlighten our thinking, .NET attribute metadata expansion is far more than this. With its characteristics, several applications and frame design can be implemented. Recently, I am implementing a project code management tool based on attribute metadata expansion, and will be shared with friends in the future.
4. to sum up
Using the .NET custom attribute to implement metadata expansion, you can add new ideas and solutions to our design, architecture. Learning an excellent framework (such as: NUNIT) is a good way. However, reading the metadata will have to involve the use of reflective mechanisms, while the performance of the reflection mechanism is low, this is designed, and it must be carefully treated.