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

在很多 Ioc 容器中,当使用者向容器请求实现了某个契约类型 (Contract Type) 的服务时 (调用类似如下方法 container.Resolve(Type contractType)),如果该服务尚未注册,而且该契约类型符合某种约定,那么容器将会自动为将该契约类型创建一个注册项 (Registration),并将该注册项添加到容器中,然后使用该注册项创建一个服务实例并将其返回给使用者。

例如,在 asp.net 应用程序中,假设我们有这样一个约定“只要契约类型是具体引用类型(不是值类型/接口/抽象类型),而且派生自 Controller 类,框架便可将其自动注册到容器中”,那么我们就可以实现类似如下效果:

public class MyController : Controller
{ }

// Create an instance of container
var container = new ObjectContainer(true);
var myController = container.Resolve<MyController>();

在上面的示例中,尽管 MyController 这个类型并未注册到容器,但由于它符合上述约定,因此容器可以自动为其构造一个对象实例并返回给调用者。实际上,这是一种称为“基于约定的配置/注册”的功能。通过这种功能,我们可以进一步减少与 Ioc 框架的耦合,同时可以更加灵活地配置要将哪些服务注册到容器中。

在 My.Ioc 中,我们通过自动注册规则 (IAutoRegistrationPolicy) 提供了类似的功能。请看下面的代码示例:

 1 using System;
 2 using System.Diagnostics;
 3 using My.Ioc;
 4 using My.Ioc.Core;
 5 using My.Ioc.Exceptions;
 6 using My.Ioc.Lifetimes;
 7 
 8 namespace UnregisteredConcreteTypeResolution
 9 {
10     public class AutoRegistrableClass
11     {
12     }
13     class CustomAutoRegistrationPolicy : IAutoRegistrationPolicy
14     {
15         #region IAutoRegistrationPolicy Member
16 
17         public bool ShouldRegister(Type concreteType)
18         {
19             return concreteType == typeof(AutoRegistrableClass);
20         }
21 
22         public ILifetimeProvider GetLifetimeProvider()
23         {
24             return new ContainerLifetimeProvider();
25         }
26 
27         #endregion
28     }
29 
30     class Program
31     {
32         static void Main(string[] args)
33         {
34             IObjectContainer container = new ObjectContainer(false);
35             AutoRegistrableClass instance;
36             try
37             {
38                 instance = container.Resolve<AutoRegistrableClass>();
39             }
40             catch (Exception ex)
41             {
42                 Debug.Assert(ex is ObjectBuilderNotFoundException);
43             }
44 
45             var option = new ContainerOption(false, new CustomAutoRegistrationPolicy());
46             container = new ObjectContainer(option);
47 
48             instance = container.Resolve<AutoRegistrableClass>();
49             Debug.Assert(instance != null);
50 
51             var instance2 = container.Resolve<AutoRegistrableClass>();
52             Debug.Assert(instance2 != null);
53             Debug.Assert(instance == instance2);
54 
55             Console.ReadLine();
56         }
57     }
58 }

在上述示例中,如果我们不显式指定自动注册规则 (IAutoRegistrationPolicy),容器默认不会提供自动注册/解析功能,因此,当我们运行到上述代码的第 38 行时,程序便会抛出异常。但当我们另外创建一个容器实例,并通过构造参数将自动注册规则 CustomAutoRegistrationPolicy 传递到新容器实例中之后,这时再来运行 instance = container.Resolve<AutoRegistrableClass>() 这行,便不会再出现异常了。

本文源码可从此处下载。

原文地址:https://www.cnblogs.com/johnny-liu/p/3962803.html