1. Reliance on
Dependence is a connection, where it is used to rely on it, and a system cannot completely avoid dependence. If one of your classes or modules does not use it in the project, congratulations, you can remove it from the project or exclude it, because there is no place to rely on it. Let's look at a simple example:
<summary>
///User Playback media file
///</summary> public
class Operationmain
{public
void PlayMedia ()
{
MediaFile _mtype = new MediaFile ();
Player _player = new player ();
_player. Play (_mtype);
}
<summary>
///player
///</summary> public
class player
{public
void play ( MediaFile file)
{
Console.WriteLine (file). FilePath);
}
<summary>
///Media file
///</summary> public
class MediaFile
{public
string FilePath {get; set;}
}
It is a simple example of a user playing a file with a player, and the user action is a PlayMedia method in the Operationmain class, opening a player and selecting a file to play. Looking first at their dependencies, it is easy to find 3 dependent player dependent MediaFile Operationmain dependent player Operationmain dependent MediaFile 2. Dependency inversion
The need for more, to use different players, playing different files, we want to abstract out, reduce coupling.
Coupling relationship is a dependency relationship, if the dependency relationship is very complex, far-reaching, difficult to maintain; the less dependent relationships, the lower the coupling, the more stable the system, so we need to reduce dependence.
Thanks to master Robert Martin, the principle of object-oriented design----dependency inversion: A. The upper modules should not be dependent on the underlying modules, which together depend on an abstraction. B. Abstraction cannot depend on the representational, the representational is dependent on the abstraction.
Understanding: A. The upper level is the user, the lower level is the user, this result is the upper layer relies on the lower layer, the lower level changes, the natural will affect the upper layer, resulting in system instability, or even far-reaching. So how to reduce reliance. Is that the upper and lower layers are going to rely on another abstraction, which is more stable, the whole is more stable.
B. Object-oriented programming-oriented abstraction or pretext-oriented programming, abstract generally more stable, the realization of the specific abstract must rely on abstraction, abstraction should not rely on other specific, should rely on abstraction.
In the above player example, we've found dependencies, and now we're going to optimize them by relying on the inversion principle.
According to the principle of the following changes: The player relies on mediafile, good to do, so that both the player and MediaFile to rely on an abstract imediafile Operationmain rely on the player, good to do, Let both Operationmain and the player rely on an abstract iplayer Operationmain rely on MediaFile, so that both Operationmain and MediaFile rely on an abstraction imediafile iplayer can not rely on specific mediafile, should rely on the specific mediafile of the abstract imediafile
The structure is simple, so the code is roughly as follows:
Namespace Demo1 {class Program {static void Main (string[] args) {Operationmain om =
New Operationmain (); Om.
PlayMedia ();
Console.ReadLine ();
}///<summary>///user Playback media file///</summary> public class Operationmain {
public void PlayMedia () {imediafile _mtype = new MediaFile (); _mtype.
FilePath = "C:\\123.mp3";
IPlayer _player = new PlayerMp4 (); _player.
Play (_mtype); } #region Interface///<summary>///player///</summary> public interface IPl
Ayer {void Play (imediafile file); ///<summary>///Media file///</summary> public interface Imediafile {Strin
G FilePath {get; set;} #endregion///<summary>///player play MP3///</summary> public class Playermp3:iPlayer {public void play (Imediafile file) {Console.WriteLine ("MP3 files" + filename).
FilePath);
}///<summary>///player play MP4///</summary> public class Playermp4:iplayer {public void Play (Imediafile file) {Console.WriteLine ("MP4 files" + filename).
FilePath); }///Player plays rmvb///</summary> public class Playerrmvb:iplayer {public void Pla Y (imediafile file) {Console.WriteLine ("RMVB files" + filename).
FilePath);
}///<summary>///default media file///</summary> public class Mediafile:imediafile
{public string FilePath {get; set;}
}
}
The above code is abstracted and can be seen, the goal is to reduce dependency, but it seems that dependency increases, such as user PlayMedia method, dependency also increases dependency interface and specific implementation, but the interface is stable, can not be considered, the specific implementation is the change, the dependency or want to play the file, Be sure to use specific players and specific files. 3. Control reversal (IoC)
In real life, is specific to the player and the specific media file does not matter, you give it a Mp3 file He can play, give it a MP4 file It can also play, you delete your media files, the player is still in, specific what player, play what file, control all of our users themselves.
The above example basically implements the isolation, the specific player with the specific media isolation, the specific player only with the media interface and player interface. But PlayMedia method inside the concrete object, write dead, control right very small, if I want to use Baidu audio and video playback, I want to change a music, can only change the code, that control how to transfer it.
We can create by reflection, the specific file name in the configuration file, this time the client code does not change, only need to change the configuration file is good, stability has been improved, as follows:
Using System; ClassLibrary Class Library project namespace ClassLibrary {#region interface///<summary>///player///</sum
Mary> public interface IPlayer {void play (imediafile file); ///<summary>///Media file///</summary> public interface Imediafile {Strin
G FilePath {get; set;} #endregion///<summary>///player play MP3///</summary> public class PLAYERMP3:IPL Ayer {public void Play (Imediafile file) {Console.WriteLine ("MP3 files" + filename).
FilePath);
}///<summary>///player play MP4///</summary> public class Playermp4:iplayer {public void Play (Imediafile file) {Console.WriteLine ("MP4 files" + filename).
FilePath); }///Player plays rmvb///</summary> public class Playerrmvb:iplayer {public void Pla Y (imediafile fiLe) {Console.WriteLine ("RMVB Files" + file.
FilePath);
}///<summary>///default media file///</summary> public class Mediafile:imediafile
{public string FilePath {get; set;}
}
}
Using System;
Using System.Reflection;
Using ClassLibrary;
Namespace Demo1 {class Program {//classlibrary library project static void Main (string[] args) {
Operationmain om = new Operationmain (); Om.
PlayMedia ();
Console.ReadLine ();
}///<summary>///user Playback media file///</summary> public class Operationmain {
Use of the public void PlayMedia () {//Control reversal (IOC)/* Assembly.Load method * (MediaFile) assembly.load ("ClassLibrary"). CreateInstance ("Classlibrary.mediafile") * The name of the Operationadd DLL file in Load ("Operationadd"), where there is a operationadd.dl Documents of the L. ")
* .
The namespace and class name in the Calculator.operationadd assembly in CreateInstance ("Calculator.operationadd"). * * Imediafile _mtype = (mediafile) assembly.load ("ClassLibrary").
CreateInstance ("Classlibrary.mediafile"); _mtype. FilePath = "c:\\123. mp4 "; IPlayer _player = (PLAYERMP3) assembly.load ("ClassLibrary").
CreateInstance ("Classlibrary.playermp3"); _player.
Play (_mtype);
}
}
}
This object is which, all by the configuration file to control, the specific object of control to the configuration file, which is often said control reversal.
Control inversion The IOC is the abbreviation of inversion's control, which is to say that the controlling power of the object is transferred to a third party, such as transfer to the IOC container, it is a creation factory, what object you want, it gives you what object, with the IOC container, the dependency is changed, The original dependencies were gone, and they all depended on the IOC container to establish their relationship through the IOC container. 4. Dependency Injection (DI)
The above mentioned control reversal, is a concept, but also to be implemented, the above configuration file is also a way to implement. Dependency Injection presents concrete ideas.
Dependency Injection di is the dependency injection abbreviation, which proposes "which East control has been reversed and shifted." , it also gives the answer: "The creation of dependent objects is reversed".
The so-called dependency injection is that the IOC container dynamically injects a dependency into the object during its operation.
In the above example, which depends on the injection, the dependent object needs to obtain an instance of the place, that is, the PlayMedia method, need to iplayer specific objects and imediafile specific objects, find a place to start from here, in order to control these two objects flexibly, Must be outside to control the instantiation of two objects, provide external operations is necessary, can be a property, can be a method, can be a constructor, in general, you can control it elsewhere, the following will be injected with unity, using the constructor injection, the code is as follows:
<summary>
///User Playback media file
///</summary> public
class Operationmain
{
Imediafile _ Mtype;
IPlayer _player;
Public Operationmain (IPlayer player, Imediafile mtype)
{
_player = player;
_mtype = Mtype;
}
public void PlayMedia ()
{
_player. Play (_mtype);
}
<summary>
///player
///</summary> public
interface IPlayer
{void Play
( Imediafile file);
}
<summary>
///default player
///</summary> public
class Player:iplayer
{
public void Play (Imediafile file)
{
Console.WriteLine (file). FilePath);
}
<summary>
///Media file
///</summary> public
interface imediafile
{
string FilePath {get; set;}
}
<summary>
///Default media file
///</summary> public
class Mediafile:imediafile
{
public string FilePath {get; set;}
}
Give the Operationmain Class A constructor, because unity has a constructor injection, the calling code is as follows:
Static UnityContainer container = new UnityContainer ();
static void Init ()
{
container. Registertype<iplayer, player> ();
Container. Registertype<imediafile, mediafile> ();
static void Main (string[] args)
{
init ();
Operationmain OP1 = container. Resolve<operationmain> ();
Op1. PlayMedia ();
Operationmain OP3 = container. Resolve<operationmain> ();
Op3. PlayMedia ();
Common way
Operationmain op2 = new Operationmain (new Player (), New MediaFile ());
Op2. PlayMedia ();
Console.read ();
}
See, the unity of the function is far more than these, you can initialize when more than N, directly later use, without using new, there are instances of the cycle of control, configuration files and other flexible control, you can see unity (specifically not the scope of this section) of the description.