My.Ioc 代码示例——注册项的注销和更新
当您需要从 Ioc 容器中注销/删除一个注册项的时候,您会怎么做呢?
有人曾经在 stackoverflow 上提问“如何从 Unity 中注销一个注册项”。对于这个问题,有人的回答是“有趣。你为什么要这样做?”,也有人试图提出一些变通的解决办法,例如通过自定义 LifetimeManager 来实现注销等等。在作者看来,这些其实都不是根本的解决办法。因为服务的注册/注销本身是一个容器级过程,当中会涉及到一些中间对象的创建/清理 (Dispose) 以及不同对象之间的协调,本应由容器来提供支持才对。
遗憾的是,在目前常见的大多数 Ioc 容器中,几乎都不提供此项功能。就作者目前所知,只有一个 Castle Windsor 曾经提供过 Unregister 功能,后来还在 3.0 版本中给去掉了,原因是这些方法 (Unregister) 有问题和瑕疵 (The methods were implementation of "remove component from the container" feature which was flawed and problematic, hecen was scraped)。
服务注销/删除的情况是如此,至于服务更新(在服务注销之后再注册新的服务以替换和更新原有服务)的功能,那更不用说了。
这种情况让作者感到很困惑。难道服务不会过期作废 (Obsolete) 吗?难道服务一旦注册之后,真的不需要注销/更新吗?作者觉得不是这样的。以作者微薄的认知,也可以举出至少两个场景是需要上述功能的:插件环境(在插件环境中,随着插件的更新,有可能需要更新服务)和面向服务环境(在面向服务环境中,服务随时可能会启用/停用/更新)。
因此,作者决定在自己的 My.Ioc 框架中提供注册项的注销/更新功能以试图解决上述问题。用法很简单,可参见下面示例代码:
using System;
using System.Diagnostics;
using My.Ioc; namespace ServiceUpdate
{
#region Test Types public interface IService
{
string Name { get; }
} public abstract class Service : IService
{
public string Name
{
get { return GetType().Name; }
}
} public class Service1 : Service
{
} public class Service2 : Service
{
} public interface IServiceConsumer
{
IService Service { get; }
} public class ServiceConsumer : IServiceConsumer
{
readonly IService _service; public ServiceConsumer(IService service)
{
_service = service;
} public IService Service
{
get { return _service; }
}
} #endregion class Program
{
static void Main(string[] args)
{
IObjectRegistration serviceRegistration;
IObjectContainer container = new ObjectContainer(false);
container.Register<IService, Service1>().Return(out serviceRegistration);
container.Register<IServiceConsumer, ServiceConsumer>();
container.CommitRegistrations(); var consumer = container.Resolve<IServiceConsumer>();
Debug.Assert(consumer != null);
Debug.Assert(consumer.Service != null);
Debug.Assert(consumer.Service.Name == "Service1"); container.Unregister(serviceRegistration);
container.Register<IService, Service2>().Return(out serviceRegistration);
container.CommitRegistrations(); consumer = container.Resolve<IServiceConsumer>();
Debug.Assert(consumer != null);
Debug.Assert(consumer.Service != null);
Debug.Assert(consumer.Service.Name == "Service2"); Console.ReadLine();
}
}
}
源码可在此处下载,压缩包中包含了 My.Ioc 框架的源码和本示例以及其他一些示例的源码。
My.Ioc 代码示例——注册项的注销和更新的更多相关文章
- My.Ioc 代码示例——如何使用默认构造参数,以及如何覆盖默认构造参数
在 Ioc 世界中,有些框架(例如 Autofac/NInject/Unity)支持传递默认参数,有些框架(例如 SimpleInjector/LightInjector 等)则不支持.作为 My.I ...
- My.Ioc 代码示例——使用观察者机制捕获注册项状态的变化
在 My.Ioc 中,要想在服务注销/注册时获得通知,可以通过订阅 ObjectBuilderRegistered 和 ObjectBuilderUnregistering 这两个事件来实现.但是,使 ...
- My.Ioc 代码示例——实现自动注册/解析
在很多 Ioc 容器中,当使用者向容器请求实现了某个契约类型 (Contract Type) 的服务时 (调用类似如下方法 container.Resolve(Type contractType)), ...
- My.Ioc 代码示例——使用条件绑定和元数据(可选)构建插件树
本文旨在通过创建一棵插件树来演示条件绑定和元数据的用法. 说“插件树”也许不大妥当,因为在一般观念中,谈到插件树,我们很容易会想到 Winform/Wpf 中的菜单.举例来说,如果要在 Winform ...
- My.Ioc 代码示例——避免循环依赖
本文的目的在于通过一些示例,向大家说明 My.Ioc 支持哪些类型的依赖关系.也就是说,如何设计对象不会导致循环依赖. 在 Ioc 世界中,循环依赖是一个顽敌.这不仅因为它会导致 Ioc 容器抛出异常 ...
- My.Ioc 代码示例——属性和方法注入
在 My.Ioc 中,我们可以指定让容器在构建好对象实例之后,自动为我们调用对象的公共方法或是为对象的公共属性赋值.在解析对象实例时,容器将根据我们在注册对象时指定的方法调用或属性赋值的先后顺序,调用 ...
- My.Ioc 代码示例——利用 ObjectBuilderRequested 事件实现延迟注册
在使用 Ioc 框架时,一般我们建议集中在一个称为 Composition Root(其含义请参见下面的小注)的位置来注册 (Register) 和解析 (Resolve) 服务.这种做法的目的在于限 ...
- My.Ioc 代码示例——谈一谈如何实现装饰器模式,兼谈如何扩展 My.Ioc
装饰器模式体现了一种“组合优于继承”的思想.当我们要动态为对象增加新功能时,装饰器模式往往是我们的好帮手. 很多后期出现的 Ioc 容器都为装饰器模式提供了支持,比如说 Autofac.在 My.Io ...
- My.Ioc 代码示例——Lifetime 和 ILifetimeScope
很多 Ioc 框架在创建对象的过程中,都会采取某种方式来缓存/复用/释放已构建的对象.在 My.Ioc 中,这个目的是通过 Lifetime/ILifetimeScope 来实现的.其中,Lifeti ...
随机推荐
- mapreduce (四) MapReduce实现Grep+sort
1.txt dong xi cheng xi dong cheng wo ai beijing tian an men qiche dong dong dong 2.txt dong xi cheng ...
- Java中接口与实例化
一.问题引入 前两天学代理模式的时候想到的,接口可不可以new呢? 接口是特殊的抽象类,接口的方法都默认为 public abstract 的... 抽象的方法不 ...
- The Wedding Juicer
poj2227:http://poj.org/problem?id=2227 题意:给你一块矩形区域,这个矩形区域是由一个个方格拼起来的,并且每个方格有一个高度.现在给这个方格灌水,问最多能装多少水. ...
- ios开发学习--歌词处理--解析lrc文件
我觉得要想解析lrc 首先大家应该了解一下lrc文件的结构,大家可以去看一下**百科 我这里粗略的写一下: ■ 时间标签(Time-tag) 形式为"[mm:ss]"(分钟数:秒数 ...
- AVR单片机RC触摸
RC电容触摸感应按键1:RC感应原理 RC采样原理就是通过测量感应极电容的微小变化,来感知人体对电容式感应器(按键.轮键或者滑条)的感应.电极电容(C)通过一个固定的电阻(R)周期性地充放电.(原文件 ...
- autotrace显示Statistics很多信息为0(转)
一朋友使用autotrace查看数据库执行计划发现结果如下,Statistics中很多信息为0,这个肯定是不正常现象,什么都可以为0,consistent gets也不可能为0. SQL> se ...
- vijos1514天才的记忆
P1514天才的记忆 背景 神仙飞啊飞 描述 从前有个人名叫W and N and B,他有着天才般的记忆力,他珍藏了许多许多的宝藏.在他离世之后留给后人一个难题(专门考验记忆力的啊!),如果谁能轻松 ...
- 网络流(二分):BZOJ 3993: [SDOI2015]星际战争
Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈 地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型 ...
- BFS zoj 1649
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1649 //hnldyhy(303882171) 11:12:46 // z ...
- Seek the Name, Seek the Fame - POJ 2752(next运用)
题目大意:小猫是非常有名气的,所以很多父母都来找它给孩子取名字,因为找的人比较多,小猫为了摆脱这个无聊的工作,于是它发明了一种取名字的办法,它把孩子父母的名字合在一起,然后从这个名字里面找一个前缀,并 ...