当您需要从 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 代码示例——注册项的注销和更新的更多相关文章

  1. My.Ioc 代码示例——如何使用默认构造参数,以及如何覆盖默认构造参数

    在 Ioc 世界中,有些框架(例如 Autofac/NInject/Unity)支持传递默认参数,有些框架(例如 SimpleInjector/LightInjector 等)则不支持.作为 My.I ...

  2. My.Ioc 代码示例——使用观察者机制捕获注册项状态的变化

    在 My.Ioc 中,要想在服务注销/注册时获得通知,可以通过订阅 ObjectBuilderRegistered 和 ObjectBuilderUnregistering 这两个事件来实现.但是,使 ...

  3. My.Ioc 代码示例——实现自动注册/解析

    在很多 Ioc 容器中,当使用者向容器请求实现了某个契约类型 (Contract Type) 的服务时 (调用类似如下方法 container.Resolve(Type contractType)), ...

  4. My.Ioc 代码示例——使用条件绑定和元数据(可选)构建插件树

    本文旨在通过创建一棵插件树来演示条件绑定和元数据的用法. 说“插件树”也许不大妥当,因为在一般观念中,谈到插件树,我们很容易会想到 Winform/Wpf 中的菜单.举例来说,如果要在 Winform ...

  5. My.Ioc 代码示例——避免循环依赖

    本文的目的在于通过一些示例,向大家说明 My.Ioc 支持哪些类型的依赖关系.也就是说,如何设计对象不会导致循环依赖. 在 Ioc 世界中,循环依赖是一个顽敌.这不仅因为它会导致 Ioc 容器抛出异常 ...

  6. My.Ioc 代码示例——属性和方法注入

    在 My.Ioc 中,我们可以指定让容器在构建好对象实例之后,自动为我们调用对象的公共方法或是为对象的公共属性赋值.在解析对象实例时,容器将根据我们在注册对象时指定的方法调用或属性赋值的先后顺序,调用 ...

  7. My.Ioc 代码示例——利用 ObjectBuilderRequested 事件实现延迟注册

    在使用 Ioc 框架时,一般我们建议集中在一个称为 Composition Root(其含义请参见下面的小注)的位置来注册 (Register) 和解析 (Resolve) 服务.这种做法的目的在于限 ...

  8. My.Ioc 代码示例——谈一谈如何实现装饰器模式,兼谈如何扩展 My.Ioc

    装饰器模式体现了一种“组合优于继承”的思想.当我们要动态为对象增加新功能时,装饰器模式往往是我们的好帮手. 很多后期出现的 Ioc 容器都为装饰器模式提供了支持,比如说 Autofac.在 My.Io ...

  9. My.Ioc 代码示例——Lifetime 和 ILifetimeScope

    很多 Ioc 框架在创建对象的过程中,都会采取某种方式来缓存/复用/释放已构建的对象.在 My.Ioc 中,这个目的是通过 Lifetime/ILifetimeScope 来实现的.其中,Lifeti ...

随机推荐

  1. iOS判断手机中是否 有 SIM卡---备用

    [CTSIMSupportGetSIMStatus() isEqualToString:kCTSIMSupportSIMStatusNotInserted]可以判断是否插入了sim卡. 前提是把下面的 ...

  2. text-decoration属性

    一.在CSS1中,text-decoration有六个值: text-decoration:none  //默认,定义标准的文本,没有任何样式,正常显示 text-decoration:underli ...

  3. matplotlib.pyplot 绘图详解 matplotlib 安装

    apt-get install python-matplotlib 转载自: http://www.cnblogs.com/qianlifeng/archive/2012/02/13/2350086. ...

  4. Android NetWorkUtil

    package com.android.hcframe.netdisc.util; import java.io.BufferedReader; import java.io.InputStreamR ...

  5. 动态规划(斜率优化):BZOJ 1010 【HNOI2008】 玩具装箱

    玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8218  Solved: 3233[Submit] Description P 教授要去 ...

  6. 杂题 UVAoj 107 The Cat in the Hat

     The Cat in the Hat  Background (An homage to Theodore Seuss Geisel) The Cat in the Hat is a nasty c ...

  7. oracle 表查询(2)

    使用逻辑操作符号 问题:查询工资高于500 或者是岗位为MANAGER 的雇员,同时还要满足他们的姓名首字母为大写的J? or job = 'MANAGER') and ename LIKE 'J%' ...

  8. Andriod视频http://pan.baidu.com/share/link?shareid=7300&uk=3339495714

    老罗Android开发 视频教程           一.Android入门介绍 视频教程     1.1 android系统介绍   1.3 如何搭建android开发环境   1.5 androi ...

  9. ubuntu 下修改host文件

    原文地址:http://www.cnblogs.com/kingcat/archive/2012/02/23/2364509.html 有些时候,我们需要让某些域名指向本地,来实现调试,下面介绍下ub ...

  10. [Locked] Verify Preorder Sequence in Binary Search Tree

    Verify Preorder Sequence in Binary Search Tree Given an array of numbers, verify whether it is the c ...