Using default constructor and parameterised constructor in unity c# -


i have application uses unity fw resolve objects throughout. have done change framework , classes can seen in code comment "new change"

the wrapper class looks like

public static class contractresolver {         public static t resolve<t>() //this been used in many places in application         {             iunitycontainer container = new unitycontainer();             var section = (unityconfigurationsection)configurationmanager.getsection("unity");             section.containers.default.configure(container);             return container.resolve<t>();         }          //new change: new function suppose return instance of parameterised constructor         public static t resolve<t>(parameteroverride[] parameteroverrides)         {             iunitycontainer container = new unitycontainer();             var section = (unityconfigurationsection)configurationmanager.getsection("unity");             section.containers.default.configure(container);             return container.resolve<t>(parameteroverrides);         } } 

the configuration looks like

  <unity>     <containers>       <container>         <types>           <type type ="unitytest.iimagerepositoryservice, unitytest" mapto="unitytest.imagerepositoryservice, unitytest"/>         </types>       </container>     </containers>   </unity> 

the classes , interface looks like

public interface iimagerepositoryservice {     bool exists(string imagename); }  public class imagerepositoryservice : iimagerepositoryservice {     private readonly string mfiltername = "standardimagefilter";      //[injectionconstructor]     public imagerepositoryservice()     {         databasequeryprovider.query("image", mfiltername);     }      //new change. constructor accepts parameter         //[injectionconstructor]     public imagerepositoryservice(string filtername)     {         mfiltername = filtername;         databasequeryprovider.query("image", filtername);     }      public bool exists(string imagename)     {         console.writeline("the image " + imagename + " found in filter " + mfiltername);         return true;     }  } 

the usage looks like

var servicedefault = contractresolver.resolve<iimagerepositoryservice>(); servicedefault.exists("myimage.bmp"); 

the new changes breaks old usage. i.e.

var servicedefault = contractresolver.resolve<iimagerepositoryservice>(); 

throws exception resolution of dependency failed, type = "unitytest.iimagerepositoryservice", name = "(none)". exception occurred while: while resolving. exception is: invalidoperationexception - type string cannot constructed. must configure container supply value.

i have new functionality @ same time not want break old functionality.

 var servicedefault = contractresolver.resolve<iimagerepositoryservice>();  servicedefault.exists("myimage.bmp"); 

should display message in console "the image myimage.bmp found in filter standardimagefilter"

var parameteroverride1 = new parameteroverride("filtername", "filter1"); var servicefilter1 = contractresolver.resolve<iimagerepositoryservice>(new[] { parameteroverride1 }); servicefilter1.exists("myimage.bmp"); 

should display message in console "the image myimage.bmp found in filter filter1"

var parameteroverride2 = new parameteroverride("filtername", "filter2"); var servicefilter2 = contractresolver.resolve<iimagerepositoryservice>(new[] { parameteroverride2 }); servicefilter2.exists("myimage.bmp"); 

should display message in console "the image myimage.bmp found in filter filter2"

how solve problem?

if want resolve same type (in case iimagerepositoryservice) have different calls resolve invoke different constructors need use named registrations.

in case can in xml configuration:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">   <container>     <register type ="unitytest.iimagerepositoryservice, unitytest" mapto="unitytest.imagerepositoryservice, unitytest">       <constructor />     </register>     <register name="parameterizedrepository"                type="unitytest.iimagerepositoryservice, unitytest"                mapto="unitytest.imagerepositoryservice, unitytest">       <constructor>         <param name="filtername" value="dummyvalue" />       </constructor>     </register>   </container> </unity> 

note, i've used unity 2 (and 3) configuration style.

so tells unity when resolving using name "parameterizedrepository" invoke constructor parameter named "filtername". i've used dummy value here because going override value @ runtime anyway:

var imagerepositoryservice = container.resolve<iimagerepositoryservice>(     "parameterizedrepository",      new parameteroverride("filtername", "filter2")); 

so that's how want using unity in terms of wrapper class should add name parameter:

public static class contractresolver {     //new change: new function suppose return instance of parameterised constructor     public static t resolve<t>(string name, params parameteroverride[] parameteroverrides)     {         iunitycontainer container = new unitycontainer();         var section = (unityconfigurationsection)configurationmanager.getsection("unity");         section.containers.default.configure(container);         return container.resolve<t>(name, parameteroverrides);     } } 

a few unsolicited comments (in spirit of trying helpful):

  • it looks using unity version 1. if so, might want consider upgrading (version 3 released recently) , if not using unity version 1, might want consider changing xml configuration syntax use newer approach using loadconfiguration() extension method.

  • i'm not sure why every call contractresolver.resolve() creates new unity container , loads configuration. bit of performance hit. usually, create container , load configuration once , use instance lifetime of application.

  • i can understand how tempted hide container implementation behind contractresolver addition of parameteroverride (which unity specific) abstraction becoming bit leaky.


Comments

Popular posts from this blog

java - Run a .jar on Heroku -

java - Jtable duplicate Rows -

validation - How to pass paramaters like unix into windows batch file -