1 依赖的例子
新建接口IServiceProvider,代码如下所示。
namespace InjectExp
{
public interface IServiceProvider
{
void ExecuteServiceMothod();
}
}
新建类ServiceProvider,实现接口IServiceProvider,代码如下所示。
using System;
namespace InjectExp
{
public class ServiceProvider:IServiceProvider
{
public void ExecuteServiceMothod()
{
Console.WriteLine("Excute service provider's method!");
}
}
}
新建ServiceUser类,ServiceUser类中初始化ServiceProvider类,并调用方法ExecuteServiceMothod()输出字符串"Excute service provider's method!"。
using System;
namespace InjectExp
{
public class ServiceUser
{
public void DoSomething()
{
ServiceProvider serviceProvider = new ServiceProvider();
serviceProvider.ExecuteServiceMothod();
}
}
}
编写使用ServiceUser类的Program类代码,如下所示。
namespace InjectExp
{
class Program
{
static void Main(string[] args)
{
ServiceUser serviceUser = new ServiceUser();
serviceUser.DoSomething();
}
}
}
下面给出前面代码中出现的所有对象的关系图。
由图可以看出,ServiceUser类强依赖于ServiceProvider类。
2 通过依赖注入实现解耦
下面通过依赖注入来实现ServiceUser类与ServiceProvider类的解耦。
新建接口IServiceInjectManager,该接口用于注入的实现。
namespace InjectExp
{
public interface IServiceInjectManager
{
void InjectService(IServiceProvider serviceProvider);
}
}
修改类ServiceUser代码,使其实现接口IServiceInjectManager。
using System;
namespace InjectExp
{
public class ServiceUser:IServiceInjectManager
{
private IServiceProvider serviceProvider;
public void InjectService(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public void DoSomething()
{
serviceProvider.ExecuteServiceMothod();
}
}
}
接着,修改Program类的代码。
namespace InjectExp
{
class Program
{
static void Main(string[] args)
{
IServiceProvider serviceProvider = new ServiceProvider();
ServiceUser serviceUser = new ServiceUser();
serviceUser.InjectService(serviceProvider);
serviceUser.DoSomething();
}
}
}
在Program类中初始化类ServiceProvider,并通过InjectService()方法将初始化后的ServiceProvider实例注入类ServiceUser中。
这样一来,我们就不用在ServiceUser类中实现ServiceProvider类的初始化了。
同样,给出代码中所有对象的关系图。
由图可以看出,此时的ServiceUser类不再依赖于ServiceProvider类,实现了两者之间的解耦。
3 依赖注入的三种方式
我们这用使用的是Interface注入的方式,除了Interface注入的方式外,还有Constructor注入和Setter注入等方法。
- Constructor注入
若使用Constructor注入,ServiceUser类的代码应该如下所示。
using System;
namespace InjectExp
{
public class ServiceUser
{
private IServiceProvider serviceProvider;
public ServiceUser(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public void DoSomething()
{
serviceProvider.ExecuteServiceMothod();
}
}
}
此时,Program类的代码应该如下所示。
namespace InjectExp
{
class Program
{
static void Main(string[] args)
{
IServiceProvider serviceProvider = new ServiceProvider();
ServiceUser serviceUser = new ServiceUser(serviceProvider);
serviceUser.DoSomething();
}
}
}
- Setter注入
若使用Setter注入,ServiceUser类的代码应该如下所示。
using System;
namespace InjectExp
{
public class ServiceUser
{
private IServiceProvider serviceProvider;
public IServiceProvider ServiceProvider
{
get { return serviceProvider; }
set { serviceProvider = value; }
}
public void DoSomething()
{
serviceProvider.ExecuteServiceMothod();
}
}
}
此时,Program类的代码应该如下所示。
namespace InjectExp
{
class Program
{
static void Main(string[] args)
{
IServiceProvider serviceProvider = new ServiceProvider();
ServiceUser serviceUser = new ServiceUser();
serviceUser.ServiceProvider = serviceProvider;
serviceUser.DoSomething();
}
}
}
4 类构造器Assembler
实现依赖注入后,我们就不再需要在ServiceUser类中实例化ServiceProvider类了。
我们还可以引入一个第三方的类Assembler(构造器),让他专门负责实例化ServiceProvider类,而ServiceUser只需要得到满足IServiceProvider约定的实例就可以了。
此时,Program客户类就可以使用Assembler类来完成类的实例化了。
当然,Assembler还可以为我们做更多的事,我们这里就不详细介绍了。
最后给出加入Assembler后的对象关系图。
好了,就到这里了。