An analysis of the AUTOFAC of IOC Container (v)

Source: Internet
Author: User

There are several ways to parse a fetch:Resolve
Class program{    static void Main (string[] args)    {        var builder = new Containerbuilder ();        Builder. Registertype<class_1> ();   If you comment out this sentence, the following resolve will throw an exception         icontainer container = Builder. Build ();        Class_1 CLAS1 = container. Resolve<class_1> ();        Console.WriteLine (CLAS1. ID);        Console.Write ("Press any key to continue ...");        Console.readkey ();    }}

This is not a problem if the type is already registered, and can get to the instance object of the registered type, but if the type is not registered, it will throw an exception if the resolve parse is obtained directly.

resolveoptional
Class program{    static void Main (string[] args)    {        var builder = new Containerbuilder ();        Builder. Registertype<class_1> ();  This comments out the type registration code        IContainer container = Builder. Build ();        Class_1 CLAS1 = container. Resolveoptional<class_1> ();        Console.WriteLine (CLAS1 = = null?) "NULL": CLAS1. Id.tostring ());    This will output null        console.write ("Press any key to continue ...");        Console.readkey ();    }}

We can use Resolveoptional to parse the fetch, and when the type is not registered, the Resolveoptional method returns null as the result.

Tryresolve
Class program{    static void Main (string[] args)    {        var builder = new Containerbuilder ();        Builder. Registertype<class_1> ();  This comments out the type registration code        IContainer container = Builder. Build ();        Class_1 clas1 = null;        if (container. Tryresolve<class_1> (out clas1))        {            Console.WriteLine (clas1. Id);        }        else        {//This will be executed            Console.WriteLine ("null");        }        Console.Write ("Press any key to continue ...");        Console.readkey ();    }}

This is the same way as the int32.tryparse we commonly use. Using the out parameter and returning a bool type indicates whether the type instance was successfully obtained.

Other related contentResolve Object Construction method selection principle

When we register a type that has more than one construction method, what is the construction method that will prevail when resolve? The answer is-- as many parameters as possible , below we analyze with an example:

Class program{static void Main (string[] args) {var builder = new Containerbuilder (); Builder.        Registertype<constructorclass> (); Builder.        Registertype<class2> (); Builder.        Registertype<class3> (); var container = Builder.        Build (); var obj = container.        Resolve<constructorclass> ();        Console.WriteLine (obj);        Console.Write ("Press any key to continue ...");    Console.readkey ();    }}//Construction method Test class constructorclass{private Class1 _clas1;    Private Class2 _clas2;    Private CLASS3 _CLAS3 = null;    Public Constructorclass () {_clas1 = null; _CLAS2 = new Class2 {Id =-1};    } public Constructorclass (Class1 clas1, Class2 clas2) {_clas1 = clas1; _clas2 = CLAS2;    } public Constructorclass (Class2 clas2, Class3 clas3) {_clas2 = Clas2; _clas3 = CLAS3; } public Constructorclass (Class2 clas2, CLASS3 CLAS3, guid guid) {_clas1 = new Class1 {Id = Guid}; _clAS2 = CLAS2;    _CLAS3 = CLAS3; } public Constructorclass (Class1 clas1, Class2 clas2, Class3 clas3) {_clas1 = clas1; _clas2 = CLAS2; _clas3    = CLAS3; } public override string ToString () {return string. Format ("{{class1.id: {0}, Class2.id: {1}, CLASS3: {2}}}", _clas1 = = null? "NULL": _CLAS1. Id.tostring (), _CLAS2 = = null? "NULL": _clas2. Id.tostring (), _CLAS3 = = null?    "NULL": "NOT NULL"); }}//constructor method parameter type class class1{public Guid Id {get; set;}} Constructor method parameter type class class2{public int Id {get; set;}} Constructor method parameter type class class3{}

The final output is {Class1.Id:null, class2.id:0, Class3:not null}, and the final execution is the third construction method (the parameter is Class2, CLASS3).

by literally stating "Max parameters", then the last constructed method or the penultimate constructor is supposed to be executed, but why is it a third?

Let go of the third constructor of why we do it. "If you are doing a third constructor, what are the values assigned to the CLASS2 and CLASS3 parameters respectively?" Where does the value come from? "Here comes the construction injection that will be talked about later. We can see that when we do type registration, we register CLASS2 and CLASS3, and Constructorclass is obtained by AUTOFAC, so the values of the CLASS2 and CLASS3 parameters are initialized by AUTOFAC. , Class2 and CLASS3 do not have a custom construction method, so the default null constructor method is called.

After knowing the reason for the initialization and assignment of the CLASS2 and CLASS3 parameters, let's take a look at the previous question, in fact, now it's clear, because the last two constructors, one requires an additional GUID type parameter, and the other requires a Class1 type parameter, and these two types are not registered , if the two constructor methods are called, then AUOTOFAC will not know what values should be assigned to these two parameters, so AUTOFAC finally chooses the third constructor method.

We also need to note that if the GUID parameter of the second-to-last constructor is given a default value, then the construction method that is chosen for the final selection will be the constructor.

Public Constructorclass (Class2 clas2, CLASS3 clas3, GUID guid = Default (GUID)) {    _clas1 = new Class1 {Id = Guid};
   
    _CLAS2 = CLAS2;    _CLAS3 = CLAS3;}
   

If you continue to retrofit the last construction method on the basis of the second penultimate construction method above, and assign the CLASS1 parameter to null by default, the exception will be thrown when resolve gets the Constructorclass instance at the end. Because of the maximum number of principles, there are two of the maximum parameters of the construction method, Autofac do not know which should be chosen to execute. The exception information tells us that we can use Usingconstructor to solve this problem (the usage of usingconstructor will be explained in the following blog post).

Public Constructorclass (Class2 clas2, Class3 clas3, Class1 clas1 = null) {    _CLAS1 = clas1;    _CLAS2 = CLAS2;    _CLAS3 = CLAS3;}

  

Focus:

Understanding the priority principle of the construction method, the method of resolving the acquisition is relatively simple and easy to use, and the acquisition of the parameter is less used in the actual coding, which can not be seen at present, because there is no actual use of AUTOFAC in the programming process. Follow-up posts will be slowly explained.

parse to get the pass parameter

We understand the principle that Autofac chooses the method of construction when resolve, the parameters in the maximum number of parameters can be either registered or assigned to default values, and in addition to these two methods, the parameter is specified at resolve . We can choose to construct more parameters by resolve Shishun:

var obj = container. Resolve<constructorclass> (New Namedparameter ("GUID", Guid.NewGuid ()));

This only modifies this resolve code, and the rest of the code does not change. In resolve, a namedparameter,namedparameter is passed in to indicate that the parameter is matched by name, and the code above indicates that the GUID.NEWGUID value is passed to the constructor parameter named GUID. This code finally executes the fourth constructor method. Because the fourth constructor is a constructor that can match the maximum number of parameters (the first two parameter types are registered to AUTOFAC, the last parameter is passed in by resolve when the Namedparameter is passed in).

Resolve method Signature is:resolve<t> (this icomponmentcontext context, params parameter[] parameters)

The first parameter is the container we use, we focus on the second parameter--a mutable parameter array, parameter is an abstract class, where Namedparameter is a subclass of parameter, In addition to the namedparameter, there are several seed arches resolve used:

Parameter type

Parameter description

Namedparameter

Match by name

Positionalparameter

Match according to Index, note: Starting index is 0

Typedparameter

Match by type, note: Pass in multiple typedparameter of the same type, all parameters of that type will take the value of the first Typedparameter

Resolvedparameter

Receive two func parameters, two func signatures all receive two identical parameters ParameterInfo and Icomponmentcontext, the first parameter is the information of the parameter (often use radiation friends should be familiar with), The second parameter is still used as a icontainer. The return value of the first Func is bool, indicating whether the current Resolvedparameter uses the currently matched parameter, and if true, the second func is executed, and the second Func returns an object that is used to populate the construction parameter values.

Here is an example of these parameter used for reference:

Class program{static void Main (string[] args) {var builder = new Containerbuilder (); Builder.        Registertype<parameterclass> (); var container = Builder.        Build (); Container. Resolve<parameterclass> (New Namedparameter ("value", "Namedparameter"),//Match parameter with Name value n EW Typedparameter (typeof (int), 1),//match the parameter of type int to new Positionalparameter (4, "Positionalparamete R "),//Match the fifth parameter (note that the index position starts from 0) new Typedparameter (typeof (int),-1),//This will be discarded because there is already a type of int in front of the typed                Parameter new Resolvedparameter (///The first func parameter is used to return a parameter that is compliant, this requires that the parameter is a class, and the namespace is not the beginning of the system, so the fourth parameter will match the (PI, cc) = Pi. Parametertype.isclass &&!pi. The second func parameter, ParameterType.Namespace.StartsWith ("System"), executes when the first Func execution result is true and is used to assign a value to the parameter, that is, the value of the fourth parameter is the execution knot of this Func        (PI, cc) = new Temp {Name = "resolveparameter"}); The final output is: {x:1, Y: 1, Value: ' Namedparameter ', temp.        Name: ' Resolveparameter ', obj: ' Positionalparameter '} console.write ("Press any key to continue ...");    Console.readkey (); }}class parameterclass{public Parameterclass (int x, int y, string value, Temp temp, object obj) {CONSOLE.WR Iteline ("{{x:{0}, Y:{1}, Value: ' {2} ', temp. Name: ' {3} ', obj: ' {4} '} ', x, y, value, temp.    Name, obj); }}class temp{public string Name {get; set;}}

An analysis of the AUTOFAC of IOC Container (v)

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.