zoukankan      html  css  js  c++  java
  • 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();
            }
        }
    }
    View Code

    源码可在此处下载,压缩包中包含了 My.Ioc 框架的源码和本示例以及其他一些示例的源码。

  • 相关阅读:
    Netty源码分析--Channel注册(上)(五)
    Netty源码分析--初始化Options,添加处理器(四)
    Netty源码分析--创建Channel(三)
    【2015 Week Task】
    【Mood 20】DailyBuild 4月
    【Gradle】 Gradle 综合
    【JS 综合】JS综合
    【IOS】IOS综合
    【起航计划 001】2015 起航计划 踏在起跑线上
    【HTML5】HTML5 综合
  • 原文地址:https://www.cnblogs.com/johnny-liu/p/3962441.html
Copyright © 2011-2022 走看看