Discussion on the new object in the analysis of the Resolve method of Castle Windsor

Source: Internet
Author: User

Dependency Injection Framework Castle Windsor parse an instance from a container (that is, call the Resolve method), by invoking the constructor of the object to be parsed and returning it, the question is: which constructor does it call?

    • Non-parametric constructors
    • A constructor with parameters that are not dependent on injection
    • parameter is a constructor that relies on injection
    • A constructor that has multiple parameters and is dependent on injection

With this problem, I wrote a test code.

Test 1:

There is only one parameterless constructor:

Ctortest Class (Use Windsor to parse this class in a console program)

    Public class ctortest    {       publicstringgetset;}          Public ctortest ()        {            = $"Themessage is from {nameof (ctortest)}";        }          Public void showmessage ()        {            Console.WriteLine (Message);        }    }

The console main code looks like this:

class program    {        staticvoid Main (string[] args)        {            new  WindsorContainer ();            Ioccontainer.register (component.for<CtorTest> (). Implementedby<ctortest>(). Lifestylesingleton ());                         var instance = ioccontainer.resolve<ctortest>();            Instance. ShowMessage ();        }    }

Test results (the default constructor is the same as the non-parametric constructor property):

Test 2

There is only one constructor with a parameter but not a dependency injection (no parameterless constructor)

The Ctortest code is as follows:

 Public string Get Set ; }          Public Ctortest (string   message)        {            = $"Themessage is from {nameof ( ctortest)}";        }          Public void showmessage ()        {            Console.WriteLine (Message);        }    }

The test result, of course, throws an exception:

If you provide a default value for this parameter (for example, String message= ""), resolve will call this constructor, and if you add an parameterless constructor, resolve will invoke the parameter, such as adding a parameter constructor with two default values, which will call two arguments. So here's the conclusion: there is a parameter with The default value first (the number of arguments first), and then no parameter .

Test 3:

There is a constructor with parameters that is dependent on injection, and a parameterless constructor, and two constructors with default value parameters.

Add a Sub class:

     Public class Sub    {        publicstringgetset;}          Public Sub ()        {            = $"Themessage is from {nameof (Sub)}";        }    }

The ctor class code is as follows:

   Public class ctortest    {       publicstringgetset;}          Public ctortest ()        {            = $"Themessage is from {nameof (ctortest)}";        }

Public Ctortest (String message = "Message1", String message2= "Message2")
{
Message = $ "The message is from {nameof (ctortest)} and {message} and {message2}";
}

 Public Ctortest (sub sub)        {            = Sub. Message;        }          Public Ctortest (string"")        {            = $"Themessage is from {nameof ( ctortest)}";        }          Public void showmessage ()        {            Console.WriteLine (Message);        }    }

Main is as follows:

classProgram {Static voidMain (string[] args) {IWindsorContainer Ioccontainer=NewWindsorContainer (); Ioccontainer.register (Component.for<CtorTest> (). Implementedby<ctortest>(). Lifestylesingleton ());
// inject Sub into container ioccontainer.register (component.for<sub> (). Implementedby<sub>(). Lifestylesingleton ()); varInstance = ioccontainer.resolve<ctortest>(); Instance. ShowMessage (); } }

Test results:

As you can see from the results , you create an instance by using a constructor with a parameter that is a dependency injection, even if you have a constructor that has 2 parameters with a default value .

Test 4

Two parameters that are dependent on the injected constructor

Add a SUB2 class:

     Public class SUB2    {        publicstringgetset;}          Public Sub2 ()        {            = $"Themessage is from {nameof (SUB2)}";        }    }

The ctor class code is as follows:

     Public classCtortest { Public stringMessage {Get;Set; }  Publicctortest () {Message= $"The message is from {nameof (ctortest)}"; }         // Note: I deliberately put this in front of the sub parameter's constructor Public    ctortest (Sub2 sub2) {Message = sub2.        Message; }        Public Ctortest (sub sub) {Message = Sub.        Message; } PublicCtortest (stringMessage ="") {Message= $"The message is from {nameof (ctortest)}"; }         Public voidShowMessage () {Console.WriteLine (Message); }    }

The main class code is as follows:

    classProgram {Static voidMain (string[] args) {IWindsorContainer Ioccontainer=NewWindsorContainer (); Ioccontainer.register (Component.for<CtorTest> (). Implementedby<ctortest>(). Lifestylesingleton ());
//inject the sub2 into the container, and notice I deliberately put sub2 in front of the sub.Ioccontainer.register (Component.for<sub2> (). Implementedby<sub2>(). Lifestylesingleton ()); //inject the sub into the containerIoccontainer.register (Component.for<sub> (). Implementedby<sub>(). Lifestylesingleton ()); varInstance = ioccontainer.resolve<ctortest>(); Instance. ShowMessage (); } }

Test results:

Although I put Sub2 's constructor and registration in front of the sub, I finally called the constructor with the sub parameter. So what's the order of it? by modifying the name of the class (for example, by changing the SUB2 to the name in front of the sub, such as S, the constructor of the s parameter is called)

Test 5

There are two constructors with parameters that are dependent on injection

Put the ctortest in the class.

         Public ctortest (Sub2 sub2)        {            = sub2. Message;        }

Modified into

         Public ctortest (Sub2 sub2,sub Sub)        {            = sub2. Message +environment.newline + Sub. Message;         }

Test results:

It calls the modified constructor, which means that it first calls the one with the most arguments.

Final total:

Resolve the number of arguments and arguments through dependency injection constructors, if there are more than one constructor with the same number of arguments, the first is called by the parameter type name (the name should be the fully qualified name, no test), and if there is no such constructor, A constructor that has a number of arguments and has a default value is called first.

Discussion on the new object in the analysis of the Resolve method of Castle Windsor

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.