First, why use the Dependency injection framework
The dependency injection framework is also called the IOC container. It acts as a decoupling between classes and classes
Let's see why we need to use the dependency injection framework to give a few pears:
1, highly-coupled class
There is an order class, the order class is used for order operations, and the DataAccess uses SQL Server to query for orders. Look at the code:
Public classOrder {PrivateDataAccess dataaccess =NewDataAccess (); Public stringQueryorder () {returnDataaccess.queryorder (); } } Public classDataAccess { Public stringQueryorder () {return "SQL Server Query Order"; } }
Seeing these two classes (order,dataaccess), they appear highly coupled. If the product Wang suddenly rabies Dafa let us change to MySQL mode query, we have to modify the order class of private dataaccess data = new DataAccess () and DataAccess Queryorder method. this is a violation. Open Closure principle (open for expansion, closed for modification) , of course, a project is not just an order operation, but also a shopping cart, product, and so on, and that change will be a nightmare.
2, using the dependency reversal principle to improve
Rely on reverse principle formula: high-level modules should not rely on low-tier modules, to rely on abstraction, do not rely on concrete.
The formulas listen very much, in fact, it is not difficult to understand, look at the following class diagram, order is equivalent to a high-level module, Sqlserverdata and mysqldata equivalent to the underlying module, high-level module depends on the interface, so you can change the underlying module at any time
We now abstract dataaccess as interfaces, enabling Sqlserverdata and Mysqldata to implement Idataaccess
Public classOrder {PrivateIdataaccess DataAccess =NewMysqldata (); Public stringQueryorder () {returnDataaccess.queryorder (); } } Public Interfaceidataaccess {stringQueryorder (); } Public classsqlserverdata:idataaccess { Public stringQueryorder () {return "SQL Server Query Order"; } } Public classmysqldata:idataaccess { Public stringQueryorder () {return "MySQL Query order"; } }
Now our high-level module depends on the interface, if the product Wang again asked us to change the Oracle database, we can add another Oracledata class, then implement the Idataaccess interface, and then in the Order class private idataaccess DataAccess = new Mysqldata () changed to private idataaccess dataaccess = new Oracledata (). Although the changes have been reduced, we have modified the class. But we do not want to modify the class, you can change the data access, which needs to be decoupled, need to use the IOC container, our Ninject finally come out, the appearance fee is not low Oh!
Second, actual combat ninject
1, using the registration mechanism
First install a Ninject DLL, we install with NuGet.
① Anti-key project reference, check manage NuGet packages
② Search Ninject, click Install
③ code implementation (only for order class operations, product class operations consistent with order class)
Idataaccess:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace registerninject{ publicinterface idataaccess { String Queryorder ();} }
Mysqldataorder:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceregisterninject{ Public classmysqldataorder:idataaccess { Public stringQueryorder () {return "MySQL Query order"; } }}
Sqlserverdataorder:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceregisterninject{ Public classsqlserverdataorder:idataaccess { Public stringQueryorder () {return "SQL Server Query Order"; } }}
Register:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingNinject;//Introducing Namespacesnamespaceregisterninject{ Public classRegister {PrivateStandardkernel _kernel =NewStandardkernel (); //Register Here PublicRegister () {_kernel. Bind<IDataAccess> (). To<mysqldataorder>(); //_kernel. Bind<idataaccess> (). To<sqlserverdataorder> (); //_kernel. Bind<idataproduct> (). To<sqlserverdataproduct> (); } //Get PublicTinterface get<tinterface>() { return_kernel. Get<tinterface>(); } Public voidDispose () {_kernel. Dispose (); } }}
Order:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceregisterninject{ Public classOrder {PrivateRegister reg =NewRegister (); Public stringQueryorder () {returnReg. Get<idataaccess>(). Queryorder (); } }}
So mom doesn't have to worry about me changing the database any more. If the product Wang again let us switch back to SQL Server database [neuropathy] (episode: Exchange Database is an example, the meaning of the IOC container is to let the class and class decoupling, not for database use!) ), we only need to modify the registration in the constructor in the Register class.
Some people say, "You still changed the Class!" "。 Register class positioning is not the same, he is a public class, specialized in providing registration mechanism. If you do not want to modify the class, you can complete the exchange of the database, it is necessary to introduce a new concept ——— hot-swap technology.
2, using an XML file (Hot swap)
Now we are using the XML file to dynamically replace the interface. We need to build an XML file. Put him in the project.
Register.xml
<? ?><name= "register"> < service= "Xmlninject.idataaccess,xmlninject" to= " Xmlninject.sqlserverdataorder,xmlninject "/></module>
Note: The module element, the name attribute, the bind element, the service attribute, the to attribute are the specified element attributes, and cannot be written otherwise. The format should be correct as well.
and then change the next Register:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingNinject;//Introducing NamespacesusingNINJECT.EXTENSIONS.XML;//Introducing Namespacesnamespacexmlninject{ Public classRegister {PrivateStandardkernel _kernel =NewStandardkernel (); //You don't have to change this here anymore, just the XML file. PublicRegister () {varSettings =NewNinjectsettings () {loadextensions =false }; _kernel=NewStandardkernel (Settings,Newxmlextensionmodule ()); _kernel. Load ("Xml/register.xml"); } //Get PublicTinterface get<tinterface>() { return_kernel. Get<tinterface>(); } Public voidDispose () {_kernel. Dispose (); } }}
In the future to replace the interface, directly change the XML file can be.
SOURCE Download Http://pan.baidu.com/s/1sjJXVrv
Fast as lightning, ultra-lightweight based. NET platform's dependency injection framework Ninject