C # Advanced Series--MEF Implementation of design "loose coupling" (iv): constructor injection

Source: Internet
Author: User

The first day of the 11 holiday today, this reason to go out, but Bo Lord the greatest pleasure is to sit in front of the computer to see all traffic jams, by the way write blog, a little harvest is good. The knowledge of MEF, has previously shared three, why today this article? Because yesterday to share the domain Services, using the MEF injected with the method of the parameter constructor, Bo main Curiosity, intends to dig a little deeper, this article to do a summary of this knowledge point.

Or a list of the previous three articles, to the MEF do not know the friend, you can first look at:

    • C # Advanced Series--MEF realization of "loose coupling" in design (i.)
    • C # Advanced Series--MEF Implementation of "loose coupling" in Design (II.)
    • C # Advanced Series--MEF Implementation of design "loose coupling" (end: interface-oriented programming)
I. Review of knowledge points

We know that MEF is one of the ways of IOC, its main function is decoupling, MEF plus interface-oriented programming, can make your design more flexible. We know that constructors of classes can be overloaded, and we can pass arguments to an object through constructors. So what if our MEF also needs to pass a constructor function? Don't worry, there is our magical importingconstructor for you to solve.

Second, code example

As a sharing code, Bo Master or intends to use the front of the DDD service in the field of the demo, now learn to sell, O (∩_∩) o~

1. Prepare the code:

As a MEF import and export object, let's start by looking at three warehousing interfaces and implementing

 Public Interface Iuserrepository:irepository<tb_users>    {        IEnumerable<TB_USERS> getusersbyrole ( Tb_role orole);    }
[Export (typeof(iuserrepository))]      Public class Userrepository:efbaserepository<tb_users>, iuserrepository    {                public Ienumerable<tb_users> getusersbyrole (tb_role orole)        {            throwNew notimplementedexception ();        }    }

     Public Interface Irolerepository:irepository<tb_role>    {            }
    [Export (typeof(irolerepository))]      Public class Rolerepository:efbaserepository<tb_role>, irolerepository    {    }

     Public Interface Iuserrolerepository:irepository<tb_userrole>    {    }
    [Export (typeof(iuserrolerepository))]      Public class Userrolerepository:efbaserepository<tb_userrole>, iuserrolerepository    {    }
2. Constructors pass in a single parameter

Look directly at the code:

[Export (typeof(Ipowermanagerdomainservice))]  Public classPowermanagerdomainservice:ipowermanagerdomainservice {PrivateIuserrepository _userrepository =NULL; PrivateIrolerepository _rolerepository =NULL; PrivateIuserrolerepository _userrolerepository =NULL; [Importingconstructor] PublicPowermanagerdomainservice (iuserrolerepository ouserrolerepository) {_userrolerepository=ouserrolerepository; }}

Why is it possible to pass the parameters Iuserrolerepository ouserrolerepository smoothly through the importingconstructor feature here? Remember the previous preparation code, Iuserrolerepository's implementation class Userrolerepository above is labeled export [Export (typeof (Iuserrepository))], so the parameters can be imported into the smooth. Or take a look at the calling code:

       [Import]        publicgetset;}         Static void Main (string[] args)        {            varnew program ();            Regisgter.regisgter (). Composeparts (Oprogram);            Console.readkey ();        }

To debug the code look at:

3. Constructors pass in multiple parameters

In fact, a number of parameters and the above individual parameters are not much different

[Importingconstructor]          Public Powermanagerdomainservice (iuserrepository ouserrepository, irolerepository orolerepository)        {            = ouserrepository;             = orolerepository;        }

Also requires iuserrepository and irolerepository types to have corresponding export.

4. The constructor parameter has multiple exports

The above example is the default warehousing interface type is only one export case, when the actual project, business logic is more complex, an interface often there are multiple implementations of the export of classes, in this case we will do? For example, the Iuserrepository storage interface has two implementation classes:

 [Export ("Userrepository_a", typeof   ( Iuserrepository)]  public  class  Userrepository_a:efbaserepository<tb_users>,iuserrepository {public  ienumerable<tb_users> Getusersbyrole (Tb_role orole) { throw  new   NotImplementedException (); }    }
[Export ("userrepository_b"typeof(iuserrepository))]      Public class Userrepository_b:efbaserepository<tb_users>, iuserrepository    {                public Ienumerable<tb_users> getusersbyrole (tb_role orole)        {            throwNew notimplementedexception ();        }    }

In this case, if we write it directly inside the constructor,

[Importingconstructor]          Public Powermanagerdomainservice (iuserrepository ouserrepository, irolerepository orolerepository)        {            = ouserrepository;             = orolerepository;        }

It must be an error. Then our solution is:

[Importingconstructor]          Public Powermanagerdomainservice ([Import ("userrepository_a"typeof( iuserrepository))]iuserrepository ouserrepository, irolerepository orolerepository)        {            =  ouserrepository;             = orolerepository;        }
5. Import of multiple constructors

Knowing so much, we also want to expand, we know that constructors can be overloaded, a class can have more than one constructor. So if we want to tag the Importingconstructor attribute at the same time on more than one constructor, and then call different constructors as needed, is that really OK? For example, we want to write this:

[Export (typeof(Ipowermanagerdomainservice))]  Public classPowermanagerdomainservice:ipowermanagerdomainservice {PrivateIuserrepository _userrepository =NULL; PrivateIrolerepository _rolerepository =NULL; PrivateIuserrolerepository _userrolerepository =NULL; [Importingconstructor] PublicPowermanagerdomainservice (iuserrolerepository ouserrolerepository) {_userrolerepository=ouserrolerepository; } [Importingconstructor] PublicPowermanagerdomainservice ([Import (typeof(iuserrepository))] Iuserrepository ouserrepository, Irolerepository orolerepository) {_userrepository=ouserrepository; _rolerepository=orolerepository; }}

Can you do that? Let's take a test:

The wish is good, but the exception is cruel! See the specifics of the exception: because the constructor could not be selected for construction. Make sure that the type has a default constructor or that there is a constructor labeled "System.ComponentModel.Composition.ImportingConstructorAttribute". It is clear that the MEF's Importingconstructorattribute feature does not support the case where multiple constructors are annotated at the same time. Take Importingconstructorattribute to the definition and discover that it has no other properties available

Is the blogger's demand too wonderful? Puzzled for a long while, still no solution was found. Later bloggers thought carefully, Perhaps the focus of the problem, MEF is generally the case with interface-oriented programming, that is, normally we define a variable of an interface type, for example:

[Import]          Public Get set; }

It allows you to have multiple implementations of an interface, and if you have multiple constructors, you can simply write multiple implementations of an interface to do it, by importing different implementation classes to replace the usage of different constructors . I do not know whether the park friends have a better solution? The most generous comment ~ ~

C # Advanced Series--MEF Implementation of design "loose coupling" (iv): constructor injection

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.