IoC学习

说IoC之前,我们先来说个很简单业务模型

1.保存系统日志到物理文件上

这个只要定义个ILog接口,并由FileLog类去具体实现即可。

View Code
 1     public class LogInfo
 2     {
 3         public string UserId { get; set; }
 4 
 5         public string IP { get; set; }
 6 
 7         public string Content { get; set; }
 8 
 9         public DateTime Time { get; set; }
10     }
11 
12 
13     public interface ILog
14     {
15         void Save(LogInfo info);
16     }
17 
18     public class FileLog : ILog
19     {
20         public virtual void Save(LogInfo info)
21         {
22             Console.WriteLine("the log had been save in file");
23         }
24     }

客户端调用如下。

View Code
 1         public void SaveFileLog()
 2         {
 3             ILog log = new FileLog();
 4             LogInfo info = new LogInfo();
 5             info.UserId = "one@gmail.com";
 6             info.IP = "192.168.1.1";
 7             info.Content = "user login";
 8 
 9             log.Save(info);
10         }

但是,现在如果需求有增加了呢?

2.保存到数据库呢?

嗯,在开个类不就得了?

View Code
1     public class DBLog : ILog
2     {
3         public void Save(LogInfo info)
4         {
5             Console.WriteLine("the log had been save in db");
6         }
7     }

至于客户端的调用,修改下也就可以了

View Code
 1         public void SaveDBLog()
 2         {
 3             ILog log = new FileLog();
 4             LogInfo info = new LogInfo()
 5             {
 6                 UserId = "one@gmail.com",
 7                 IP = "192.168.1.1",
 8                 Content = "user login"
 9             };
10 
11             log.Save(info);
12         }

到这边事情好像都OK了,But,有没有更好的代码组织方式呢?

我讨厌在客户端这边一直写重复的代码(调用接口实例)。

那么我们是不是可以这样写呢?

View Code
 1     public class LogService
 2     {
 3         public ILog Log { get; private set; }
 4 
 5         public LogInfo Info { get; private set; }
 6         
 7 
 8         public LogService(ILog log,LogInfo info)
 9         {
10             this.Log = log;
11             this.Info = info;
12         }
13 
14         public void Save()
15         {
16             this.Log.Save(this.Info);
17         }
18     }
19 
20     public class Client
21     {
22         public void SaveLog()
23         {
24             LogInfo info = new LogInfo();
25             info.UserId = "one@gmail.com";
26             info.IP = "192.168.1.1";
27             info.Content = "user login";
28 
29             ILog log = new FileLog();
30 
31             LogService service = new LogService(log, info);
32 
33             service.Save();
34         }
35     }

似乎看起来,貌似还不错嘛。但是还能不能更好呢?

毕竟,保存日志的介质在不同场景会有不同需求,这个时候,我们做移植时还要修改源代码,这违反了OCP原则

这个时候,我们可以利用反射来创建具体接口实例。

总结下:

IoC主要目的是松散耦合。

具体是,在对象外部通过容器创建维护对象依赖的对象,并通过参数来传递。

因为对象依赖的对象总是要有地方进行new(创建)的,而这步动作通过个容器来做。

这个容器应有很多实现方式,在Spring框架中,应该是利用反射+Xml配置文件来实现(这点不确定,只是猜测)

原文地址:https://www.cnblogs.com/haiyidao/p/2705962.html