Ioc容器Autofac系列(3)-- 三种注册组件的方式
2016-04-26 23:16
459 查看
简单来说,所谓注册组件,就是注册类并映射为接口,然后根据接口获取对应类,Autofac将被注册的类称为组件。 虽然可像上篇提到的一次性注册程序集中所有类,但AutoFac使用最多的还是单个注册。这种注册共有三种方式,其中最简单的就是用As方法,例如,ArrayList继承了IEnumerable接口,若将其注册到Autofac中,写法如下所示:
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<ArrayList>().As<IEnumerable>();
// then
IContainer container = builder.Build();
ArrayList result = (ArrayList)container.Resolve<IEnumerable>();
有时难免碰到多个类映射到同一种接口,比如ArrayList和SortedList都继承了IEnumerable接口,为了准确获取想要的类型,就有了第二种方式--Named方法,可根据字符串注册并解析相应的类。代码如下:
builder.RegisterType<ArrayList>().Named<IEnumerable>("array");
builder.RegisterType<SortedList>().Named<IEnumerable>("sort");
// then
IContainer container = builder.Build();
ArrayList result = (ArrayList)container.ResolveNamed<IEnumerable>("array");
SortedList result1 = (SortedList)container.ResolveNamed<IEnumerable>("sort");
然而相对于字符串,枚举更易读易用,但在Autofac中使用枚举会有些麻烦,因为Named只接受字符串,必须将枚举转换成字符串才能使用。比如,现在用ListType枚举来代替“array”和“sort”字符串。如下所示:
public enum ListType{ Array, Sort }
builder.RegisterType<ArrayList>().Named<IEnumerable>(ListType.Array.ToString());
这种转换略显笨拙,而且让枚举失去原有价值。于是,为不多此一举,第三种方式就产生了--Keyed方式,该方法可以接受任何类型作为参数。以上文中的ListType枚举为例,代码如下:
builder.RegisterType<ArrayList>().Keyed<IEnumerable>(ListType.Array);
builder.RegisterType<SortedList>().Keyed<IEnumerable>(ListType.Sort);
// then
IContainer container = builder.Build();
ArrayList result = (ArrayList)container.ResolveKeyed<IEnumerable>(ListType.Array);
SortedList result1 = (SortedList)container.ResolveKeyed<IEnumerable>(ListType.Sort);
无论使用As、Named还是Keyed都可达到注册目的,根据个人喜好而定。但从功能上来讲,Autofac的设计者推荐第三种。
IIndex<ListType, IEnumerable> allList = container.Resolve<IIndex<ListType, IEnumerable>>();
ArrayList result = (ArrayList)allList[ListType.Array];
SortedList result1 = (SortedList)allList[ListType.Sort];
IIndex中第一个泛型参数要跟注册时一致,这里是ListType枚举。其他两种注册方法没有这样的索引查找功能,这也是为什么设计者推荐Keyed注册的原因之一。
参考文献:http://nblumhardt.com/2010/08/the-iindexkv-relationship-type/
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<ArrayList>().As<IEnumerable>();
// then
IContainer container = builder.Build();
ArrayList result = (ArrayList)container.Resolve<IEnumerable>();
有时难免碰到多个类映射到同一种接口,比如ArrayList和SortedList都继承了IEnumerable接口,为了准确获取想要的类型,就有了第二种方式--Named方法,可根据字符串注册并解析相应的类。代码如下:
builder.RegisterType<ArrayList>().Named<IEnumerable>("array");
builder.RegisterType<SortedList>().Named<IEnumerable>("sort");
// then
IContainer container = builder.Build();
ArrayList result = (ArrayList)container.ResolveNamed<IEnumerable>("array");
SortedList result1 = (SortedList)container.ResolveNamed<IEnumerable>("sort");
然而相对于字符串,枚举更易读易用,但在Autofac中使用枚举会有些麻烦,因为Named只接受字符串,必须将枚举转换成字符串才能使用。比如,现在用ListType枚举来代替“array”和“sort”字符串。如下所示:
public enum ListType{ Array, Sort }
builder.RegisterType<ArrayList>().Named<IEnumerable>(ListType.Array.ToString());
这种转换略显笨拙,而且让枚举失去原有价值。于是,为不多此一举,第三种方式就产生了--Keyed方式,该方法可以接受任何类型作为参数。以上文中的ListType枚举为例,代码如下:
builder.RegisterType<ArrayList>().Keyed<IEnumerable>(ListType.Array);
builder.RegisterType<SortedList>().Keyed<IEnumerable>(ListType.Sort);
// then
IContainer container = builder.Build();
ArrayList result = (ArrayList)container.ResolveKeyed<IEnumerable>(ListType.Array);
SortedList result1 = (SortedList)container.ResolveKeyed<IEnumerable>(ListType.Sort);
无论使用As、Named还是Keyed都可达到注册目的,根据个人喜好而定。但从功能上来讲,Autofac的设计者推荐第三种。
通过IIndex索引查找被Keyed标识过的类
如果使用Keyed方法注册类,可通过Autofac内置索引来查找指定的值,这个索引的类型是IIndex<Tkey,TValue>,以上文的枚举为例,可通过索引完成解析,代码如下:IIndex<ListType, IEnumerable> allList = container.Resolve<IIndex<ListType, IEnumerable>>();
ArrayList result = (ArrayList)allList[ListType.Array];
SortedList result1 = (SortedList)allList[ListType.Sort];
IIndex中第一个泛型参数要跟注册时一致,这里是ListType枚举。其他两种注册方法没有这样的索引查找功能,这也是为什么设计者推荐Keyed注册的原因之一。
参考文献:http://nblumhardt.com/2010/08/the-iindexkv-relationship-type/
相关文章推荐
- 标题背景加蓝色
- java.lang.ClassNotFoundException: net.sf.cglib.proxy.Callback
- 1001. 二哥摘苹果
- 在OS X 上安装MongoDB
- 002如何构建hadoop集群环境?
- bzoj 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛(树形DP)
- Windwos 08R2_DNS+AD安装图文
- c++第四次实验
- LocalNotification 与远程通知的是如何操作的?
- 随心所欲的DateTime显示格式
- TLD学习(3) arthurv版TLD
- Mysql cluster初学
- swift面向对象之方法
- 关于服务器raid的一个记录
- iOS中UISearchBar(搜索框)使用总结
- 关于服务器raid的一个记录
- xUtils里使用HttpUtils时出现的无法访问HttpRequestBase的错误
- python连接mysql和mongo数据库
- 围圈小朋友报数退出问题
- JavaScript 面向对象编程