在上篇文章《System.ComponentModel.Component入门》中,介绍了.NET本身的解决方案,既然.NET已经有了解决方案,为什么要自己实现呢?先看看使用.NET的方式写的代码:
1、通过GetService获取的组件,无法自动加入新的容器;
在.NET中,GetService方法是由Site定义的(实际实现是容器实现的),且不包含加入新容器的参数,所以新创建的组件只能笨拙的加入容器(第3行)。
2、商业组件内部代码耦合了Container实现;
在第1行,只能自己实例化一个容器,不管是耦合Container还是耦合自己的容器,都是违反了注射依赖的初衷。
3、难以理解
正如上一篇文章中的回复所说的,“我还是不懂”,是的,.NET的站点和容器的设计的确让人难以理解。
基于上面的问题,我设计了一个新的接口定义:
使用实例:
1、在类的定义中,继承自ServiceBase,他是IService的基础实现,当然你可以自己实现IService,实现非常简单;
2、当你需要使用别的服务时,通过Context创建新的容器,并在新的容器中创建服务,这样新的服务就自动加入新的容器,并自动初始化了Context属性。
1 using (IContainer container = new Container()) {
2 IOrderService orderService = GetService(typeof(IOrderService)) as IOrderService;
3 container.Add(orderService);
4 }
2 IOrderService orderService = GetService(typeof(IOrderService)) as IOrderService;
3 container.Add(orderService);
4 }
1、通过GetService获取的组件,无法自动加入新的容器;
在.NET中,GetService方法是由Site定义的(实际实现是容器实现的),且不包含加入新容器的参数,所以新创建的组件只能笨拙的加入容器(第3行)。
2、商业组件内部代码耦合了Container实现;
在第1行,只能自己实例化一个容器,不管是耦合Container还是耦合自己的容器,都是违反了注射依赖的初衷。
3、难以理解
正如上一篇文章中的回复所说的,“我还是不懂”,是的,.NET的站点和容器的设计的确让人难以理解。
基于上面的问题,我设计了一个新的接口定义:
/// <summary>
/// 注射依赖的服务组件。
/// </summary>
public interface IService {
/// <summary>
/// 返回/设置当前服务组件的上下文。
/// </summary>
/// <remarks>
/// 不需要服务自己处理此属性,组件在初始化后,将有上层服务自动初始化。
/// 请参见:<see cref="IServiceContainer.GetService<T>"/>
/// </remarks>
IServiceContext Context { get;set;}
}
/// <summary>
/// 服务的上下文,通过他,可以获取新的容器。
/// </summary>
public interface IServiceContext {
IServiceContainer CreateContainer();
}
/// <summary>
/// 容器对象,通过他创建的服务将自动初始化 Context属性,并在容器释放后自动释放。
/// </summary>
public interface IServiceContainer : IServiceFactory, IDisposable { }
/// <summary>
/// 服务工厂接口
/// </summary>
public interface IServiceFactory {
T GetService<T>();
}
/// 注射依赖的服务组件。
/// </summary>
public interface IService {
/// <summary>
/// 返回/设置当前服务组件的上下文。
/// </summary>
/// <remarks>
/// 不需要服务自己处理此属性,组件在初始化后,将有上层服务自动初始化。
/// 请参见:<see cref="IServiceContainer.GetService<T>"/>
/// </remarks>
IServiceContext Context { get;set;}
}
/// <summary>
/// 服务的上下文,通过他,可以获取新的容器。
/// </summary>
public interface IServiceContext {
IServiceContainer CreateContainer();
}
/// <summary>
/// 容器对象,通过他创建的服务将自动初始化 Context属性,并在容器释放后自动释放。
/// </summary>
public interface IServiceContainer : IServiceFactory, IDisposable { }
/// <summary>
/// 服务工厂接口
/// </summary>
public interface IServiceFactory {
T GetService<T>();
}
使用实例:
1 public class DataService : ServiceBase, IDataService {
2
3 public void UpdateDB() {
4 using (IServiceContainer container = Context.CreateContainer()) {
5 ILogService log = container.GetService<ILogService>();
6 log.WriteLog();
7 }
8 }
9 }
2
3 public void UpdateDB() {
4 using (IServiceContainer container = Context.CreateContainer()) {
5 ILogService log = container.GetService<ILogService>();
6 log.WriteLog();
7 }
8 }
9 }
2、当你需要使用别的服务时,通过Context创建新的容器,并在新的容器中创建服务,这样新的服务就自动加入新的容器,并自动初始化了Context属性。