Unity2.0容器自动注册机制
现如今可能每个人都会在项目中使用着某种 IoC 容器,并且我们的意识中已经形成一些固定的使用模式,有时会很难想象如果没有 IoC 容器工作该怎么进展。
IoC 容器通过某种特定设计的配置,用于在运行时决定将哪些组件注入到我们的代码中。这种配置可以是基于 XML 的映射,也可以是基于 Fluent API 的设计。但随着项目代码的不断增长,配置文件总是变得越来越冗长。此时,我们该寻求某种改进措施来增强代码的可读性和可维护性。
对于 IoC 容器来讲,自动注册机制是一项非常实用的功能,并且其在某些特定的场景下特别的有效。
Unity 是微软提供的依赖注入容器,其在 2.0 版本时并不支持自动注册机制(Auto Registration),在 3.0 版本中添加了基于约定的自动注册机制(Registration By Convention)。
Codeplex 中的 Unity Auto Registration 项目通过使用 Fluent API 方式为 Unity 扩展了自动注册机制。
我们可以通过 NuGet 来添加 Unity Auto Registration 包引用。
PM> Install-Package UnityAutoRegistration
1 PM> Install-Package UnityAutoRegistration 2 Attempting to resolve dependency 'Unity (≥ 2.1.505.0)'. 3 Attempting to resolve dependency 'CommonServiceLocator (≥ 1.0)'. 4 Successfully installed 'CommonServiceLocator 1.0'. 5 You are downloading Unity from Microsoft, the license agreement to which is available at http://www.opensource.org/licenses/ms-pl. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device. 6 Successfully installed 'Unity 2.1.505.2'. 7 You are downloading UnityAutoRegistration from agovorov, the license agreement to which is available at http://autoregistration.codeplex.com/license. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device. 8 Successfully installed 'UnityAutoRegistration 1.0.0.2'. 9 Successfully added 'CommonServiceLocator 1.0' to ConsoleApplication13_UnityAutoRegistration. 10 Successfully added 'Unity 2.1.505.2' to ConsoleApplication13_UnityAutoRegistration. 11 Successfully added 'UnityAutoRegistration 1.0.0.2' to ConsoleApplication13_UnityAutoRegistration.
Unity Auto Registration 通过使用较少的代码进行配置,自动加载、搜索和匹配指定程序集中的类和接口,并形成映射注册到 Unity 中。
1 using System; 2 using Microsoft.Practices.Unity; 3 using Unity.AutoRegistration; 4 5 namespace ConsoleApplication13_UnityAutoRegistration 6 { 7 class Program 8 { 9 static void Main(string[] args) 10 { 11 IUnityContainer container = new UnityContainer(); 12 13 container 14 .ConfigureAutoRegistration() 15 .ExcludeSystemAssemblies() 16 .Include(type => type.ImplementsOpenGeneric(typeof(ICommandHandler<>)), 17 Then.Register().AsFirstInterfaceOfType().WithTypeName()) 18 .ApplyAutoRegistration(); 19 20 container 21 .ConfigureAutoRegistration() 22 .LoadAssemblyFrom(typeof(IRepository<>).Assembly.Location) 23 .ExcludeSystemAssemblies() 24 .Exclude(type => type.Name.Contains("_Proxy_")) 25 .Exclude(type => type.Name.EndsWith("_Accessor", StringComparison.Ordinal)) 26 .Include(type => type.Implements<IBaseProvider>(), Then.Register().WithName(type => "SampleProvider")) 27 .Exclude(type => type.Name == "IBaseProvider") 28 .ApplyAutoRegistration(); 29 30 container 31 .ConfigureAutoRegistration() 32 .ExcludeAssemblies(a => a.GetName().FullName.Contains("Test")) 33 .Include(If.Implements<ILogger>, Then.Register().UsingPerCallMode()) 34 .Include(If.ImplementsITypeName, Then.Register().WithTypeName()) 35 .Include(If.Implements<ICustomerRepository>, Then.Register().WithName("SampleRepository")) 36 .Include(If.Implements<IOrderManager>, 37 Then.Register() 38 .AsSingleInterfaceOfType() 39 .UsingPerCallMode()) 40 .Include(If.DecoratedWith<LoggerAttribute>, 41 Then.Register() 42 .As<IDisposable>() 43 .WithTypeName() 44 .UsingLifetime<ContainerControlledLifetimeManager>()) 45 .Exclude(t => t.Name.Contains("Trace")) 46 .ApplyAutoRegistration(); 47 48 Console.ReadKey(); 49 } 50 } 51 52 [AttributeUsage(AttributeTargets.Class)] 53 public class LoggerAttribute : Attribute { } 54 public interface ILogger { } 55 [LoggerAttribute] 56 public class MockLogger : ILogger, IDisposable { public void Dispose() { } } 57 public interface IBaseProvider { } 58 public interface IRepository<T> { } 59 public interface ICustomerRepository : IRepository<Customer> { } 60 public class CustomerRepository : ICustomerRepository { } 61 public interface IOrderManager { } 62 public class OrderManager : IOrderManager { } 63 public class Customer { } 64 public class Order { } 65 public interface ICommandHandler<T> { } 66 public class CommandHandler<T> : ICommandHandler<T> { } 67 }
所以如何你仍然需要使用 Unity 2.0/2.1 版本来管理依赖注入的配置,推荐使用 Unity Auto Registration 。