IOC的容器确实不少,unity,autofac,Castle 等等,前两种组件如何实现IOC在我之前的文章中已经做过说明了,今天主要来说一下Castle如何去实现IoC,事实上Castle是小微的一个开源项目,最早接触它是在orchard项目中,在orchard里主要用在动态代理方法拦截上,当然这是castle最重要的作用,事实上它当然也可以实现IoC了,不过,你要下载一个Castle.Windsor.dll,它主要实现ioc功能的。
说干就干,事情和前两个组件的工作场景是相似的,一个irepository,多种实现方式,ef,linq,nhibernate,ado.net等等,你可以根据你的需要去实现它,这只是最大层次上的多态,代码可能是这样:
泛型类版本
1 #region 泛型注入
2 public interface IRepository<T>
3 {
4 void Insert(T entity);
5 }
6
7 public class EFRepository<T> : IRepository<T>
8 {
9 #region IRepository<T> 成员
10
11 public void Insert(T entity)
12 {
13 Console.WriteLine("EFRepository泛型注入" + entity);
14 }
15
16 #endregion
17 }
18 #endregion
非泛型版本(泛型方法版本)
1 #region 非泛型注入
2 public interface IRepository
3 {
4 void Insert<T>(T entity);
5 }
6
7 public class EFRepository : IRepository
8 {
9 #region IRepository<T> 成员
10
11 public void Insert<T>(T entity)
12 {
13 Console.WriteLine("EFRepository非泛型注入" + entity);
14 }
15
16 #endregion
17 }
18
19 public class LINQRespository : IRepository
20 {
21 #region IRepository<T> 成员
22
23 public void Insert<T>(T entity)
24 {
25 Console.WriteLine("LINQRepository非泛型注入" + entity);
26 }
27
28 #endregion
29 }
30 #endregion
对于这两种类型,在castle配置上也略有不同,看代码:
"非泛型" service="Test.IRepository,Test" type="Test.EFRepository,Test" />
<component id="泛型" service="Test.IRepository`1,Test" type="Test.EFRepository`1,Test"
上面的代码是架构层次的,而对于具体的业务,如用户方面的业务可能有多个版本的考虑,可能有代缓存的,不代缓存的,可能有发邮件的,也可能有发短信的,这是具体业务层次的多态,代码可能是这样的:
1 #region 服务是泛型,类型不是泛型
2
3 public interface IMessageService<T>
4 {
5 void Sending(T entity);
6 }
7 public class UserService : IMessageService<User>
8 {
9
10
11 #region IMessageService<User> 成员
12
13 public void Sending(User entity)
14 {
15 Console.WriteLine("用户模块发消息,采用E-Mail方式");
16 }
17
18 #endregion
19 }
20
21 public class ProductService : IMessageService<Product>
22 {
23 #region IMessageService<Product> 成员
24
25 public void Sending(Product entity)
26 {
27 Console.WriteLine("产品模块发消息采用短信");
28 }
29
30 #endregion
31 }
32 #endregion
看上面的代码,一个发消息的业务,它对于不同的业务对象,可能有不同的实现方式,而这种方法,我们可以在配置文件中进行设置:
1 <component id="具体业务,接口为泛型,实现非泛型" service="Test.IMessageService`1[[Test.User,Test]],Test"
type="Test.UserService,Test"
整個配置文件內容如下:
<configuration>
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
</configSections>
<castle>
<components>
<component id="非泛型" service="Test.IRepository,Test" type="Test.EFRepository,Test" />
<component id="泛型" service="Test.IRepository`1,Test" type="Test.EFRepository`1,Test" />
<component id="具体业务,接口为泛型,实现非泛型" service="Test.IMessageService`1[[Test.User,Test]],Test" type="Test.UserService,Test"
而castle容器的代码也封装了一下,改了上人的低版本的,呵呵
/// <summary>
/// IOC容器
/// </summary>
public sealed class Container
{
#region Fields & Properies
/// <summary>
/// WindsorContainer object
/// </summary>
private WindsorContainer windsor;
private IKernel kernel;
public IKernel Kernel
{
get { return kernel; }
}
/// <summary>
/// 容器实例
/// </summary>
private static readonly Container instance = new Container();
public static Container Instance
{
get { return Container.instance; }
}
#endregion
#region Constructors
/// <summary>
/// Constructor Method.
/// Initialization IOC.
/// </summary>
public Container()
{
try
{
Castle.Core.Resource.ConfigResource source = new Castle.Core.Resource.ConfigResource();
XmlInterpreter interpreter = new XmlInterpreter(source);
windsor = new WindsorContainer(interpreter);
kernel = windsor.Kernel;
}
catch (Exception)
{
throw;
}
}
#endregion
#region Public Methods
/// <summary>
/// Returns a component instance by the type of service.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Resolve<T>()
{
return kernel.Resolve<T>();
}
/// <summary>
/// Release resource that be container used.
/// </summary>
public void Dispose()
{
kernel.Dispose();
}
#endregion
#region Private Methods
/// <summary>
/// Returns a component instance by the service name.
/// </summary>
/// <param name="service"></param>
/// <returns></returns>
private object Resolve(Type service)
{
return kernel.Resolve(service);
}
/// <summary>
/// Returns a component instance by the service name.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private object Resolve(String key)
{
return kernel.Resolve<object>(key);
}
#endregion
}
在程序中调用它的代码为:
();
iRepository.Insert<User>(new User { Name = "ok" });
IRepository<User> iRepository1 = Container.Instance.Resolve<IRepository<User>>();
iRepository1.Insert(new User { Name = "ok" });
IMessageService<User> r = (IMessageService<User>)Container.Instance.Resolve<IMessageService<User>>();
r.Sending(new User { Name = "ok"
运行的结果为:
感谢您的阅读!
作者:仓储大叔,张占岭,
荣誉:微软MVP