Monday, April 07, 2008

Creating Instances of internal classes using Spring.Net

Creating an instance of an internal class using Spring.Net is a little tricky. I know that, you can achieve this by adding an InternalsVisibleTo attribute to your assembly. However, the following solution also works as desired.

Say, you have an namespace named SampleClasses that contains the a public interface named 'IPublicInterface' and also an internal class named 'InternalClass' that implements the IPublicInterface interface and looks like the following -

   1: namespace SampleClasses


   2: {


   3:     public interface IPublicInterface


   4:     {


   5:         string SayHello();


   6:     }


   7: }






   1: internal class InternalClass : IPublicInterface


   2: {


   3:  


   4:     #region IPublicInterface Members


   5:  


   6:     public string SayHello()


   7:     {


   8:         return "Hello, World!";


   9:     }


  10:  


  11:     #endregion


  12: }




And also, you have an xml configuration file named 'SampleClasses.Spring.xml' containing your object definition for InternalClass and looks like the following one -





   1: <objects xmlns="http://www.springframework.net">


   2:   <object id="internalClass"


   3:           type="SampleClasses.InternalClass, SampleClasses"


   4:           >    


   5:   </object>


   6: </objects>




Now, you need to make sure the following are true -



1. 'SampleClasses.Spring.xml is compiled as an embedded resource with the assembly that holds the InternalClass class and also in the same namespace. To ensure this, right click the XML file, select Properties and Select Embedded Resource in the Build Action.



2. In your App.Config (or Web.Config, for web applications), add the following XML declarations to add the embedded XML file -





   1: <configuration>

   2:   <configSections>

   3:   <sectionGroup name="spring">

   4:     <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core, Version=1.1.0.2, Culture=neutral, PublicKeyToken=65e474d141e25e07"/>

   5:     <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core, Version=1.1.0.2, Culture=neutral, PublicKeyToken=65e474d141e25e07"/>

   6:   </sectionGroup>

   7:   </configSections>

   8:   

   9:    <spring>

  10:     <!-- Define the context : identify the source from where it gets its resources-->

  11:     <context>

  12:       <resource uri="assembly://SampleClasses/SampleClasses/SampleClasses.Spring.xml"/>      

  13:     </context>

  14:   </spring>

  15: </configuration>




Now, that you have everything ready you can simply write the following code segment to access create an instance of the internal class and hold it through the IPublicInterface as shown below-





   1: string id = "internalClass";            

   2:             IPublicInterface obj = ContextRegistry.GetContext().GetObject(id) as IPublicInterface;

   3:             Console.WriteLine("Hello = {0}", obj.SayHello());




So, you see that its simple way to create an instance of an internal type using Spring.Net given that the internal type is the type of a public Interface. If this assumption is not true, then probably you are not following the best OO designs, where you need to create instances of types that are only supposed to be internal to a namespace.



Wish it helps some of you. Send me a comment if you need the full source code and project.