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>() 这行,便不会再出现异常了。

 

本文源码可从此处下载。

你可能感兴趣的:(IOC)