一.Windsor的使用

Windsor的作为依赖注入的容器的一种,使用起来比较方便,我们直接在Nuget中添加Castle Windsor,将会自动引入Castle.Core 和 Castle.Windsor,就可以正常使用。

1.逐个组件进行注册

使用注册模块中的Component

 IWindsorContainer container = new WindsorContainer();
container.Register(Component.For<IAppleService>() //接口
.ImplementedBy<AppleService>());

在这里取一个特殊的例子,我们注册一个带有参数的的实例,我们直接使用Resolve实现兑现的注入

    public class AppleService : IAppleService
{
public AppleService(decimal price)
{
this.Price = price;
}
public decimal Price { get; set ; }
public void Output()
{
Console.WriteLine(Price);
}
}
//具体的实现注入
var apple= container.Resolve<IAppleService>(new Dictionary<string,decimal>() { { "price",222.22m} });
apple.Output();
Console.ReadLine();

在Resolve方法中提供了一个IDictionary的参数,所以我们可以通过Dictionary或者HashTable将参数传递进去。

单个组件进行注册,当我们项目中的类较少的时候还是可以的,但是我们在实际的项目中,往往都是遵循单一化的职责,创建出大量的文件,采用上面的方式将会变成一种灾难。

2.通过规则批量注册(通过类库注册)

  container.Register(Classes.FromThisAssembly()   //当前程序集,也可以用FromAssemblyInDirectory()等
.InSameNamespaceAs<CatService>() //与CatService类具有相同的命名空间
// .InNamespace("Windsor")//直接指定命名空间
.WithService.DefaultInterfaces()
.LifestyleTransient()); //临时生命周期
var apple= container.Resolve<IAppleService>(new Dictionary<string,decimal>() { { "price",222.22m} });
var cat = container.Resolve<ICatService>();
cat.Eat();
apple.Output();

详细的API可以通过BasedOnDescriptor中的详细说明机型使用

3.通过安装器Installer进新注册

因为测试代码是使用控制台程序进行测试的,上面的两种方式我们把注册的代码直接写在Main方法中,这样的方式耦合性高,同时不方便管理。所以可以采用安装器的方式进行注册

(1)通过接口IWindsorInstaller实现安装器

//定义
public class ServiceInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly() //当前程序集,也可以用FromAssemblyInDirectory()等
.InSameNamespaceAs<CatService>() //与CatService类具有相同的命名空间
.WithServiceDefaultInterfaces()//注册所有的默认的接口和实现类
.LifestyleTransient()); //临时生命周期
}
} //注册
//3.通过安装器进行注册
container.Install(FromAssembly.Named("Windsor"));
var apple= container.Resolve<IAppleService>(new Dictionary<string,decimal>() { { "price",222.22m} });
var cat = container.Resolve<ICatService>();
cat.Eat();
apple.Output();

上面通过安装器进注册的时,指定了程序集Windor下面的安装器将会被调用,那么此时有一个问题,如果我的安装器定义在当前类库的文件夹下面是否可以被注册使用呢?

通过测试发现,是可以被注册的。

另一个问题,如果我们的安装器中注册的类出现重复的,那么我们的容器中会不会重复注册?

通过测试发现,不会被重复注册,也不会报错哦。

还有一个问题

会不会报错呢?

答案是不会的,这个可以从CastleWindsor的源码中可以找到,这是有它的的实现机制决定的,会判断重复,维护这一个Dictionary

(2)通过xml配置文件

//使用配置文件  container.Install(Configuration.FromXmlFile("WindsorSetting.xml"));
var cat = container.Resolve<ICatService>();
cat.Eat();
Console.ReadLine();
//定义配置文件WindsorSetting.xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<installers>
<install type="Windsor.ServiceInstaller,Windsor"/> </installers>
<!--<components>
<component type="Windsor.CatService,Windsor" service="Windsor.ICatService,Windsor"> </component>
</components>-->
</configuration>

type中的字符串,第一个表示的是命名空间下的具体的安装器类,第二个表示程序集名称

上面的代码中我们自定义了xml文件,当然我们可以直接使用项目中app.config

//调用
container.Install(Configuration.FromAppConfig());
var cat = container.Resolve<ICatService>();
cat.Eat();
//配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup> <castle>
<installers>
<install type="Windsor.ServiceInstaller,Windsor"/>
<!--查找该程序集下所有IWindsorInstaller接口的类型进行注册-->
<!--<install assembly="WindsorInstaller"></install>--> <!--查找dll文件-->
<!--<install directory="Extensions" fileMask="*.dll"></install>-->
</installers>
</castle>
</configuration>

二.Windsor中的InstallerFactory的使用

从上面的随笔中我们可以了解到常用的windsor的注入使用的方式,那么其实还有一个很现实的问题,上面的实现方式都是没有注入顺序的,也就是说如果类1用到了另一个注入容器的类2,那么倘若类2如果在类1之后注册,那么将会报错,找不到对应的实例。其实解决这个问题也是好办的,只要我们使用Component一个类一个类的注册就OK了。其实windsor中还提供了另外的方式,那就是InstallerFactory他可以控制注入的顺序。先上代码

 public class ServiceFactory:InstallerFactory
{
public override IEnumerable<Type> Select(IEnumerable<Type> installerTypes)
{
var retval = installerTypes.OrderBy(x => this.GetPriority(x));
return retval;
} private int GetPriority(Type type)
{
var attribute = type.GetCustomAttributes(typeof(InstallerPriorityAttribute), false).FirstOrDefault() as InstallerPriorityAttribute;
return attribute != null ? attribute.Priority : InstallerPriorityAttribute.DefaultPriority;
}
}
[AttributeUsage(AttributeTargets.Class)]
public sealed class InstallerPriorityAttribute : Attribute
{
public const int DefaultPriority = ; public int Priority { get; private set; }
public InstallerPriorityAttribute(int priority)
{
this.Priority = priority;
}
}
}
//在Program中注册
  container.Install(FromAssembly.This(new ServiceFactory()));

其实在Factory中的Select的方法中会将所有的继承自IWindsorInstaller的类的类型获取到,然后我们通过特性标签的方式对Installer进行排序,这样我们就可以控制Installer被初始化的顺序了。

三.Windsor的拓展

1.泛型的注入

container.Register( Component.For(typeof(ICatService<>)).ImplementedBy(typeof(CatService<>));

2.注册顺序的简单设置

 // 取先注册的
container.Register(
Component.For<ICatService>().ImplementedBy<CatService>(),
Component.For<IAppleService>().ImplementedBy<AppleService>()
); // 强制取后注册的
container.Register(
Component.For<ICatService>().ImplementedBy<CatService>(),
Component.For<IAppleService>().Named("SelfDefinedService").ImplementedBy<AppleService>().IsDefault()
);

3.直接注册实例对象

 var cat = new CatService();
container.Register(
Component.For<ICatService>().Instance(cat)
);

依赖注入容器之Castle Windsor的更多相关文章

  1. 基于DDD的.NET开发框架 - ABP依赖注入

    返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...

  2. 小白初学Ioc、DI、Castle Windsor依赖注入,大神勿入(不适)

    过了几天,我又来了.上一篇中有博友提到要分享下属于我们abp初学者的历程,今天抽出点时间写写吧.起初,我是直接去看阳光铭睿的博客,看了一遍下来,感觉好多东西没接触过,接着我又去下了github 里面下 ...

  3. [Castle Windsor]学习依赖注入

    初次尝试使用Castle Windsor实现依赖注入DI,或者叫做控制反转IOC. 参考: https://github.com/castleproject/Windsor/blob/master/d ...

  4. Castle Windsor 使MVC Controller能够使用依赖注入

    以在MVC中使用Castle Windsor为例 1.第一步要想使我们的Controller能够使用依赖注入容器,先定义个WindsorControllerFactory类, using System ...

  5. Castle.Windsor依赖注入的高级应用_Castle.Windsor.3.1.0

    [转]Castle.Windsor依赖注入的高级应用_Castle.Windsor.3.1.0 1. 使用代码方式进行组件注册[依赖服务类] using System; using System.Co ...

  6. ASP.NET Web API - 使用 Castle Windsor 依赖注入

    示例代码 项目启动时,创建依赖注入容器 定义一静态容器 IWindsorContainer private static IWindsorContainer _container; 在 Applica ...

  7. Castle.Windsor依赖注入的高级应用与生存周期

    1. 使用代码方式进行组件注册[依赖服务类] using System; using System.Collections.Generic; using System.Linq; using Syst ...

  8. MVC Castle依赖注入实现代码

    1.MVc 实现依赖注入 public class WindsorControllerFactory : DefaultControllerFactory { private readonly IKe ...

  9. 对Castle Windsor的Resolve方法的解析时new对象的探讨

    依赖注入框架Castle Windsor从容器里解析一个实例时(也就是调用Resolve方法),是通过调用待解析对象的构造函数new一个对象并返回,那么问题是:它是调用哪个构造函数呢? 无参的构造函数 ...

随机推荐

  1. 关于MYSQL ERROR1045 报错的解决办法

    **问题描述 **ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES)或者ERROR ...

  2. 【R作图】lattice包,画多个分布柱形图,hist图纵轴转换为百分比

    一开始用lattice包,感觉在多元数据的可视化方面,确实做得非常好.各种函数,可以实现任何想要实现的展示. barchart(y ~ x) y对x的直方图 bwplot(y ~ x) 盒形图 den ...

  3. Socket网络编程--简单Web服务器(2)

    上一小节通过阅读开源的Web服务器--tinyhttpd.大概知道了一次交互的请求信息和应答信息的具体过程.接下来我就自己简单的实现一个Web服务器. 下面这个程序只是实现一个简单的框架出来.这次先实 ...

  4. js的new Date()日期的使用

    <script type="text/javascript"> //js获取某个月的天数 function days(year,month){ var dayCount ...

  5. Spring MVC学习摘要

    1. context:component-scan标签的use-default-filters属性的作用以及原理分析 http://www.cnblogs.com/hafiz/p/5875770.ht ...

  6. 解剖 Elasticsearch 集群 - 之一

    解剖 Elasticsearch 集群 - 之一 本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇.在本篇文章中,我们会讨论底层的存储模型以及 CRUD(创建.读取.更新 ...

  7. Excel中substitute替换函数的使用方法

    问题现象:在Excel中,对几千条数据按照时间顺序排序,但总是有部分数据不参与排序,单纯用单元格调整不起任何作用. 解决办法: 数据排列问题最重要的是数据格式的一致性.解决这个问题,建议按如下步骤: ...

  8. Java知多少(25)再谈Java包

    在Java中,为了组织代码的方便,可以将功能相似的类放到一个文件夹内,这个文件夹,就叫做包. 包不但可以包含类,还可以包含接口和其他的包. 目录以"\"来表示层级关系,例如 E:\ ...

  9. 第三百九十九节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署CentOS6.5安装mysql5.6

    第三百九十九节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署CentOS6.5安装mysql5.6 1.检测系统是否已经安装过mysql或其依赖,若已装过要先将其删除,否则第4步 ...

  10. 服务器部署多个tomcat(Address already in use: JVM_Bind)

    一.修改startup.bat **多个Tomcat同时运行时.不要设置 catalina_home catalina_base classes 环境变量, 修改setclasspath.bat (| ...