[Entlib] Microsoft enterprise database 5.0 learning path-Step 10: Use unity to decouple your system-Part2-learn how to use Unity (2)

Source: Internet
Author: User

In the previous articleArticleI briefly introduced how to useCodeAnd the configuration file to configure the unity container. Today, we will continue to introduce how to use the unity container.

This article will mainly introduce:

1. Relationship between registered objects.

2. register an existing object.

3. Introduction to lifetime management in unity.

 

1. Relationship between registered objects

In the previous article, we briefly introduced how to use unity to register the relationship between objects and use the registertype method to register the relationship between objects.

First, let's look at the class relationship diagram:

There are two interface classes: iclass (class Interface) and isubject (subject Interface), which have two implementation classes respectively. Now you must first register the class-related object relationships. The Code is as follows:

 Public static void registertypecode () {// register the relationship between iclass and myclass. // This is the default registration of iclass, every time you call resolve 
  
   , myclass container is returned. registertype 
   
     (); // If you perform the default registration again, the original registration will be overwritten. // container. registertype 
    
      (); // register the relationship between iclass and yourclass. // a parameter "your" is added to indicate a name registration, only when resolve 
     
       ("your") is called Will yourclass // This registration method be returned to solve the conflict container when multiple mappings need to be registered for an object. registertype 
      
        ("your"); // obtain the specific object and call iclass myclass = container. resolve 
       
         (); iclass yourclass = container. resolve 
        
          ("your"); myclass. showinfo (); yourclass. showinfo (); // The resolveall 
         
           method can be used to obtain non-default object instances registered with iclass at a time. // This is the registered object, therefore, the list contains only one yourclass ienumerable 
          
            classlist = container. resolveall 
           
             (); foreach (VAR item in classlist) {item. showinfo () ;}}
           
          
         
        
       
      
     
    
   
  

This code shows how to use the registertype method to register the relationship between objects,Note that the provided naming parameters are case-sensitive during name registration. Therefore, inputting "your" and "your" indicates not registering an object.. This section also shows how to use the resolve method to obtain the required objects and use the resolveall method to obtain the list of all objects associated with the specified object.

Other reloads of the registertype method will not be described in detail here. You canClick here to viewDetailed introduction to overload methods.

 

Next, let's take a look at how to use the configuration file for configuration (similar to the previous example). The configuration file code is as follows:

<Unity xmlns = "http://schemas.microsoft.com/practices/2010/unity"> <alias = "iclass" type = "unitystudyconsole. idemo. iclass, unitystudyconsole "/> <alias =" myclass "type =" unitystudyconsole. demo. myclass, unitystudyconsole "/> <alias =" yourclass "type =" unitystudyconsole. demo. yourclass, unitystudyconsole "/> <container name =" first "> <register type =" iclass "mapto =" myclass "/> <register type =" iclass "mapto =" yourclass "name = "Your"/> </container> </Unity>Read and call the Code as follows:
 
Public static void registertypecodeconfiguration () {// get the configuration section unityconfigurationsection = (unityconfigurationsection) configurationmanager with the specified name. getsection ("Unity"); container. loadconfiguration (section, "first"); iclass classinfo = container. resolve <iclass> (); classinfo. showinfo ();}

 

2. register an existing object

In the process of daily development, we sometimes create an object by ourselves, but you want to manage the lifecycle of the created object, in this case, you can use the registerinstance method provided by unity. The sample code is as follows:

 
Public static void registerinstance () {iclass myclass = new myclass (); iclass yourclass = new yourclass (); // register the default instance container for the myclass instance. registerinstance <iclass> (myclass); // register a named instance for your class instance, which is the same as registertype container. registerinstance <iclass> ("yourinstance", yourclass); container. resolve <iclass> (). showinfo (); container. resolve <iclass> ("yourinstance "). showinfo ();}

This code is very simple. You can use the registerinstance method to register existing objects. In this way, you can use unitycontainer to manage the lifecycle of these object instances.

It should be noted that the registerinstance is used to register an existing instance to the unitycontainer. By default, the containercontrolledlifetimemanager is used, and the life cycle is managed by the unitycontainer, unitycontainer maintains a strong reference of an object instance. After you register an existing instance with unitycontainer, each time you get an object through the resolve method, it is the same object, singleton instance is described as follows.

Because registerinstance registers an existing instance, it cannot be configured through the configuration file.

I will not detail the other reloads of the registerinstance method here. You canClick here to viewDetailed introduction to overload methods.

 

Iii. Introduction to lifetime management in Unity

We introduce unity in the system to remove the dependency between objects through unity, so that we can call the required objects according to the configuration, by default, unity will automatically help us maintain the lifecycle of these objects. Maybe the lifecycle automatically maintained by unity is not what we want, we want to change the lifecycle of these objects as needed. Next we will introduce the built-in lifecycle manager in unity.

1,Transientlifetimemanager,Transient life cycle, which is used by defaultRegistertypeIf the lifecycle manager is not specified during object link registration, the lifecycle manager is used by default. The lifecycle manager is the same as its name.ResolveOrResolveallWhen an object is called, a new object is created again.

You must note that you cannot specify this lifecycle when using registerinstance to register existing objects. Otherwise, an exception is reported.

The Code is as follows:

Public static void transientlifetimemanagercode () {// the following two types of registration results are the same container. registertype <iclass, myclass> (); container. registertype <iclass, myclass> (New transientlifetimemanager (); console. writeline ("------- transientlifetimemanager begin ------"); console. writeline ("hashcode:" + container. resolve <iclass> (). gethashcode (); console. writeline ("the second time the hashcode of the object registered by registertype is called:" + container. resolve <iclass> (). gethashcode (); console. writeline ("------- transientlifetimemanager end ------");}

The configuration file is as follows:

<Register type = "iclass" mapto = "myclass"> <lifetime type = "transient"/> <! -- <Lifetime type = "sessionlifetimemanager" value = "session #1" typeconverter = "sessionlifetimeconverter"/> --> </register>

If you want to change a lifecycle manager when registering a link in the configuration file, you only need to add <lifetime> In the <register> Configuration section (if not added, transientlifetimemanager is used by default ).

<Lifetime> has three parameters:

1) type: indicates the type of the Life Cycle manager. You can choose either the built-in type of unity or the custom type. The built-in Life Cycle manager provides smart prompts.

2) typeconverter: the conversion class of the lifecycle manager. A converter is created when you define a lifecycle manager.

3) value: Initialize the value of lifecycle manager.

Configuration File Read code:

Public static void transientlifetimemanagerconfiguration () {// gets the configuration section unityconfigurationsection = (unityconfigurationsection) configurationmanager for the specified name. getsection ("Unity"); container. loadconfiguration (section, "first"); console. writeline ("------- transientlifetimemanager begin ------"); console. writeline ("hashcode:" + container. resolve <iclass> ("transient "). gethashcode (); console. writeline ("the second time the hashcode of the object registered by registertype is called:" + container. resolve <iclass> ("transient "). gethashcode (); console. writeline ("------- transientlifetimemanager end ------");}

As shown below, we can see that each generated object is different:

 

2,Containercontrolledlifetimemanager, Container control lifecycle management. This lifecycle manager is the default Life Cycle manager used by registerinstance, that is, a single-piece instance. unitycontainer maintains a strong reference to an object instance, the same object is returned every time a call is made. The sample code is as follows:

Public static void containercontrolledlifetimemanagercode () {iclass myclass = new myclass (); // the following two types of registration results are the same container. registerinstance <iclass> ("CCL", myclass); container. registerinstance <iclass> ("CCL", myclass, new containercontrolledlifetimemanager (); container. registertype <iclass, myclass> (New containercontrolledlifetimemanager (); console. writeline ("------- containercontrolledlifetimemanager begin ------"); console. writeline ("hashcode:" + container. resolve <iclass> (). gethashcode (); console. writeline ("the second time the hashcode of the object registered by registertype is called:" + container. resolve <iclass> (). gethashcode (); console. writeline ("hashcode:" + container. resolve <iclass> ("CCL "). gethashcode (); console. writeline ("hashcode:" + container. resolve <iclass> ("CCL "). gethashcode (); console. writeline ("------- containercontrolledlifetimemanager end ------");}

The configuration file is as follows:

 
<Register type = "iclass" mapto = "myclass" name = "CCL"> <lifetime type = "Singleton"/> </register>

As shown below, we can see that each retrieved object is the same object:

 

3,Hierarchicallifetimemanager, Hierarchical lifecycle manager, which is similarContainercontrolledlifetimemanagerIt is also managed by unitycontainer, that is, a single-piece instance. HoweverContainercontrolledlifetimemanagerThe difference is that the life cycle manager is layered because the unity container can be nested, so this life cycle manager is designed for this situation. When this life cycle manager is used, the lifecycle of objects maintained by the parent container and sub-container is managed by their respective containers. The Code is as follows (registerinstance is similar, so it will not be shown here ):

Public static void hierarchicallifetimemanagercode () {container. registertype <iclass, myclass> (New hierarchicallifetimemanager (); // create a sub-container var childcontainer = container. createchildcontainer (); childcontainer. registertype <iclass, myclass> (New hierarchicallifetimemanager (); console. writeline ("------- containercontrolledlifetimemanager begin ------"); console. writeline ("the first time the hashcode of the object registered by the parent container is called:" + container. resolve <iclass> (). gethashcode (); console. writeline ("the second call to the parent container registered object hashcode:" + container. resolve <iclass> (). gethashcode (); console. writeline ("the first time you call the hashcode of the object registered by the sub-container:" + childcontainer. resolve <iclass> (). gethashcode (); console. writeline ("the second call to the sub-container registration object hashcode:" + childcontainer. resolve <iclass> (). gethashcode (); console. writeline ("------- containercontrolledlifetimemanager end ------");}

Because this level of effect cannot be configured in the configuration file, you only need to change the name of the lifecycle When configuring this type of lifecycle:

<Register type = "iclass" mapto = "myclass" name = "Hl"> <lifetime type = "hierarchical"/> </register>

The following describes how to maintain different object instances at the parent and child levels:

Here, we need to mention that the benefit of Unity's hierarchical container is that we can place objects with different lifecycles in different containers. If a sub-container is released, objects in other sub-containers are not affected, but if the parent container at the root node is released, all sub-containers will be released.

 

4,PerresolvelifetimemanagerThis lifecycle refers to the life cycle that is repeatedly referenced to solve the circular reference. Let's take a look at the official instance provided by Microsoft:

 
Public interface ipresenter {} public class mockpresenter: ipresenter {public iview view {Get; set;} public mockpresenter (iview view) {view = view ;}} public interface iview {ipresenter presenter {Get; Set ;}} public Class View: iview {[dependency] public ipresenter presenter {Get; Set ;}}

in this example, we can see that there are two interfaces ipresenter and iview, and two classes mockpresenter and view implement the two interfaces respectively, at the same time, both classes contain the object attributes of another class. This is a circular reference, and the corresponding lifecycle management is newly added for this situation, it is similar to transientlifetimemanager, but the difference is that if such a lifecycle manager is applied, a new object will be created during the first call, the previously created object instance ( single-piece instance ) is returned when you access the instance through cyclic reference again. The Code is as follows:

Public static void perresolvelifetimemanagercode () {var Container = new unitycontainer (). registertype <ipresenter, mockpresenter> (). registertype <iview, View> (New perresolvelifetimemanager (); var view = container. resolve <iview> (); var temppresenter = container. resolve <ipresenter> (); var realpresenter = (mockpresenter) view. presenter; console. writeline ("------- perresolvelifetimemanager begin ------"); console. writeline ("Object begin with perresolvelifetimemanager"); console. writeline ("view object obtained through resolve method:" + view. gethashcode (); console. writeline ("view object contained by the presenter object in the view object:" + realpresenter. view. gethashcode (); console. writeline ("Object end with perresolvelifetimemanager used"); console. writeline (""); console. writeline ("Object begin which perresolvelifetimemanager is not used"); console. writeline ("presenter object in view object:" + realpresenter. gethashcode (); console. writeline ("view object obtained through resolve method:" + temppresenter. gethashcode (); console. writeline ("the object end of perresolvelifetimemanager is not used"); console. writeline ("------- perresolvelifetimemanager begin ------");}

From the code, we can see that when registering an object, only perresolvelifetimemanager is applied to iview and view. Therefore, the second access to the view object will return the same instance.

The specific configuration file is as follows,Content About constructor injection and property injection is introduced in the next article.:

 
<Alias = "ipresenter" type = "unitystudyconsole. ipresenter, unitystudyconsole "/> <alias =" iview "type =" unitystudyconsole. iview, unitystudyconsole "/> <alias =" mockpresenter "type =" unitystudyconsole. mockpresenter, unitystudyconsole "/> <alias =" View "type =" unitystudyconsole. view, unitystudyconsole "/> <container name =" second "> <register type =" ipresenter "mapto =" mockpresenter "> <constructor> <Param name =" View "type =" iview"> </param> </constructor> </register> <register type = "iview" mapto = "View"> <lifetime type = "perresolve"/> <property name =" presenter "dependencytype =" ipresenter "> </property> </register> </container>

The code used to read the configuration file is similar to the code used to read other configuration files. The code is not displayed here. For details, see the sample code.

The details are as follows:

We can see that the hashcode of the two views object is the same, but the hashcode of the presenter object is different.

 

5,PerthreadlifetimemanagerThe life cycle manager of each thread ensures that each thread returns the same instance. The specific code is as follows:

 Public static void perthreadlifetimemanagercode () {container. registertype 
  
    (New perthreadlifetimemanager (); var thread = new thread (New parameterizedthreadstart (thread1); console. writeline ("------- perresolvelifetimemanager begin ------"); console. writeline ("Default thread begin"); console. writeline ("first call:" + container. resolve 
   
     (). gethashcode (); console. writeline ("second call:" + container. resolve 
    
      (). gethashcode (); console. writeline ("Default thread end"); thread. start (container);} public static void thread1 (Object OBJ) {var tmpcontainer = OBJ as unitycontainer; console. writeline (" in"); console. writeline ("first call:" + tmpcontainer. resolve 
     
       (). gethashcode (); console. writeline ("second call:" + tmpcontainer. resolve 
      
        (). gethashcode (); console. writeline ("New thread end"); 
      
     
    
   
  

Console. writeline ("------- perresolvelifetimemanager end ------");}

 
 

The configuration-related code is similar to the previous lifecycle manager. No code is posted here. See the sample code.

The details are as follows:

At the same time, it is recommended that you do not use perthreadlifetimemanager when using registerinstance to register an existing object, because the object has been created in a thread, if you use the lifecycle manager again, you cannot ensure that it is called correctly.

 

6,Externallycontrolledlifetimemanager, External control lifecycle manager. This lifecycle management allows you to use registertype and registerinstance to register the relationship between objects, but it only keeps a weak reference to objects, the lifecycle is put under external control, which means that you can cache or destroy this object without worrying about unitycontainer. When this object is not strongly referenced elsewhere, it will be destroyed by GC.

By default, with this lifecycle manager, the same object (single-piece instance) will be returned every time you call resolve. If you call the resolve method again after GC recycle, a new object will be created, the sample code is as follows:

Public static void externallycontrolledlifetimemanagercode () {container. registertype <iclass, myclass> (New externallycontrolledlifetimemanager (); var myclass1 = container. resolve <iclass> (); var myclass2 = container. resolve <iclass> (); console. writeline ("------- externallycontrolledlifetimemanager begin ------"); console. writeline ("first call:" + myclass1.gethashcode (); console. writeline ("second call:" + myclass2.gethashcode (); myclass1 = myclass2 = NULL; GC. collect (); console. writeline ("***** after GC collection *****"); console. writeline ("first call:" + container. resolve <iclass> (). gethashcode (); console. writeline ("second call:" + container. resolve <iclass> (). gethashcode (); console. writeline ("------- externallycontrolledlifetimemanager end ------");}

The configuration-related code is similar to the previous lifecycle manager. No code is posted here. See the sample code.

As follows:

 

This section describes how to use unitycontainer to register the relationships between objects, register the relationships between existing objects, and the built-in Life Cycle manager of unity.

 

Download Sample Code: Click here to download

(Note: The sample code in this article is based on vs2010 + unity2.0, so use vs2010 to open it. If vs2010 is not installed, copy the relevant code to the corresponding vs to run)

 

Index of a series of articles on the learning path of Microsoft enterprise database 5.0:

Step 1: getting started

Step 2: Use the vs2010 + data access module to create a multi-database project

Step 3: Add exception handling to the project (record to the database using custom extension)

Step 4: Use the cache to improve the website's performance (entlib caching)

Step 5: Introduce the entlib. validation module information, the implementation level of the validators, and the use of various built-in validators-Part 1

Step 5: Introduce the entlib. validation module information, the implementation level of the validators, and the use of various built-in validators-Part 1

Step 5: Introduce the entlib. validation module information, the implementation level of the validators, and the use of various built-in validators-Part 2

Step 6: Use the validation module for server-side data verification

Step 7: Simple Analysis of the cryptographer encryption module, custom encryption interfaces, and usage-Part 1

Step 7: Simple Analysis of the cryptographer encryption module, custom encryption interfaces, and usage-Part 2

Step 8. Use the configuration setting module and other methods to classify and manage enterprise database configuration information

Step 9: Use the policyinjection module for AOP-PART1-basic usage

Step 9: Use the policyinjection module for AOP-PART2-custom matching rule

Step 9: Use the policyinjection module for AOP-PART3 -- Introduction to built-in call Handler

Step 9: Use the policyinjection module for AOP-PART4 -- create a custom call handler to achieve user operation Logging

Step 10: Use unity to decouple your system-Part1-Why use unity?

Step 10: Use unity to decouple your system-Part2-learn how to use Unity (1)

Step 10. Use unity to decouple your system-Part2-learn how to use Unity (2)

Step 10: Use unity to decouple your system-Part2-learn how to use Unity (3)

Step 10: Use unity to decouple your system-Part3-dependency Injection

Step 10: Use unity to decouple your system-part4 -- unity & piab

Extended learning:

Extended learning and dependency injection in libraries (rebuilding Microsoft Enterprise Library) [go]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.