[MVC Study Notes] 3. Use Spring. Net application IOC (dependency inversion), spring. netioc
Now, we have basically set up the project framework, but there is still a problem in the project, that is, although the layer and layer use interfaces for isolation, but when instantiating interfaces, introduce the interface implementation class dependency, as shown in the following code:
private IUserService _userService;private IUserService UserService{ get { return _userService ?? (_userService = new UserService()); } set { _userService = value; }}
Interface-Oriented ProgrammingThe Controller should only rely on the site service layer interface, rather than the specific implementation. Otherwise, it violates the original intention of setting interfaces between layers.
In addition, if the upper layer only depends on the lower layer interface, you can use Moq, Fakes, and other Mock tools to simulate interface implementation as needed during unit testing, you can flexibly control the return values of interfaces to test various situations. If you rely on specific implementations, the project's testability will be greatly reduced, making it difficult to conduct automated unit tests.
Instead of depending on the specific implementation, you cannot use the common T = new t () method to obtain a class instance. You need to use the IOC container to perform object lifecycle, dependency and so on for unified management. Here, we will use Spring. net application IOC.
Use of Spring. Net in console programs
We will use a simple console example to demonstrate how to use Spring. Net.
Create a test class:
Namespace SpringNetDemo {public interface IClass {string Name {get; set;} Student Monitor {get; set;} string GetMsg ();} public class Class: IClass {public string Name {get; set;} public Student Monitor {get; set;} public string GetMsg () {return "Class Name:" + Name + ", class leader: "+ Monitor. name ;}} public class Student {public string Name {get; set ;}}}
There are two classes, one interface. The Student Class has a property of the string type, which is Name. In the Class, besides the Name attribute of the string type, there is also a Monitor attribute of the Student type, the GetMsg method returns the description of the current Class object, including the Class name and the Class leader name. Class implements the IClass interface.
Perform a simple test first:
IClass c6 = new Class () {Monitor = new Student () {Name = "Li "}, Name = "Class 6"}; Console. writeLine (c6.GetMsg (); Console. readKey ();
Output:
<? Xml version = "1.0" encoding = "UTF-8"?> <Objects xmlns = "http://www.springframework.net"> <description> An example that demonstrates simple IoC features. </description> <object name = "Class" type = "SpringNetDemo. class, springNetDemo "> <property name =" Name "value =" "/> <property name =" Monitor "ref =" Student "/> </object> <object name =" student "type =" SpringNetDemo. student, SpringNetDemo "> <property name =" Name "value =" "/> </object> </objects>
Create an objects root node in xml, and add the object subnodes to be generated by the container. In the type attribute of the object subnode, specify the full name (with assembly) of the class and the current namespace, if you need to assign a default value to the attributes of the current class, you can add a property node to the object node and configure its value attribute to assign an initial value to the attributes of the class, if the class property is still another class object, you can create an object node of this type and give it the name attribute. Then, you can set the ref attribute in the property node of the current property, point to the name attribute of the newly added object node.
Note: Set the xml file to "copy if new" or "always copy". Otherwise, the file will not be automatically copied to the program directory during generation.
4. Configure the Spring. Net information in the application configuration file:
<?xml version="1.0" encoding="utf-8" ?><configuration> <configSections> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/> <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> </sectionGroup> </configSections> <spring> <context> <resource uri="file://services.xml"/> </context> </spring></configuration>
Run the program to obtain the output result:
Use of Spring. Net in ASP. NET MVC
The method is similar to that in the console program.
1. Similarly, first import the dll file
<? Xml version = "1.0" encoding = "UTF-8"?> <Objects xmlns = "http://www.springframework.net">, <object type = "PMS. webApp. controllers. userController, PMS. webApp "singleton =" false "> <property name =" UserService "ref =" UserService "/> </object> </objects>
Services. xml:
<?xml version="1.0" encoding="utf-8" ?><objects xmlns="http://www.springframework.net"> <object name="UserService" type="PMS.BLL.UserService, PMS.BLL" singleton="false" > </object></objects>
For convenience of management, the Controller and business class are saved in two files. The Node rules in the file are identical to those in the console example.
3. Modify the Web. config configuration file
Public class MvcApplication: SpringMvcApplication // HttpApplication
5. Finally, modify the code in the original controller to successfully implement IOC using Spring. Net in the MVC project.
//private IUserService _userService;//private IUserService UserService//{// get { return _userService ?? (_userService = new UserService()); }// set { _userService = value; }//}private IUserService UserService { get; set; }