打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
依赖注入容器Unity Application Block快速入门

依赖注入容器Unity Application Block快速入门

概述

Unity是微软模式与实践团队开发的一个轻量级、可扩展的依赖注入容器,之前我也有过一篇文章《Enterprise Library 4.0中的依赖注入容器(Unity)预览》对其做过介绍。微软模式与时间团队已经在2月份发布了Unity February 2008 CTP版本,官方主页是:http://www.codeplex.com/unity,大家可以到网站上去下载相关的源代码。本文将通过一些示例让您对Unity使用有一个逐步的认识和了解。

准备相关代码

为了接下来的说明,我们先编写几个后面需要的接口和类:

接口ILogger

public interface ILogger{void Write(string message);}

FlatFileLogger类

public class FlatFileLogger : ILogger{public void Write(string message){Console.WriteLine(String.Format("Message:{0}", message));Console.WriteLine("Target:FlatFile");}}

DatabaseLogger类

public class DatabaseLogger : ILogger{public void Write(string message){Console.WriteLine(String.Format("Message:{0}",message));Console.WriteLine("Target:Database");}}

创建容器

在Unity中创建容器实例有两种方法,一是直接使用构造函数创建,如下代码所示:

class Program{static void Main(string[] args){        IUnityContainer container = new UnityContainer();}}

第二种通过父容器创建容器,在Unity中提供了层级容器的创建,即可以通过父容器来逐级创建容器:

图1 Unity中层级容器

通过父容器来创建容器可以使用CreateChildContainer:

class Program{static void Main(string[] args){UnityContainer parentContainer = new UnityContainer();        UnityContainer childContainer = parentContainer.CreateChildContainer();}}

采用层级容器的好处是我们可以对于有不同生命周期的对象放在不同的容器中,如果一个子容器被释放,不会影响到其它子容器中的对象,但是如果根节点处父容器释放后,所有的子容器都将被释放。

class Program{static void Main(string[] args){UnityContainer parentContainer = new UnityContainer();UnityContainer childContainer = parentContainer.CreateChildContainer();// can use both generated objects here// Dispose child containerchildContainer.Dispose();// can use only object in parent container here// Dispose parent containerparentContainer.Dispose();}}

注册接口映射

在Unity中提供了Register方法供我们在容器中注册接口映射:

class Program{static void Main(string[] args){IUnityContainer container = new UnityContainer();container.Register<ILogger, DatabaseLogger>();container.Register<ILogger, FlatFileLogger>("flatfileLogger");}}

第一个泛型参数是基类型,第二个泛型参数是组件类型,它们之间必须满足一定的泛型约束关系:

IUnityContainer Register<TFrom, TTo>() where TTo : TFrom;

另外,如果在注册组件时没有指定我们也可以使用非泛型的Register方法进行接口映射:

class Program{static void Main(string[] args){IUnityContainer container = new UnityContainer();
        container.Register(typeof(ILogger),typeof(DatabaseLogger));container.Register(typeof(ILogger),typeof(FlatFileLogger),"flatfileLogger");}}

获取对象实例

在Unity中提供了Get方法用以获取对象实例,如下代码所示:

class Program{static void Main(string[] args){IUnityContainer container = new UnityContainer();container.Register<ILogger, FlatFileLogger>();ILogger logger =  container.Get<ILogger>();logger.Write("TerryLee");}}

在上面代码中,我们在容器中注册了一个ILogger接口到FlatFileLogger的映射,当调用Get<ILogger>()方法时,将返回ILogger的一个默认的类型实例。运行代码可以看到:

在之前注册接口映射部分,Register方法有一个重载是为接口映射指定一个特定的名称,这样我们可以根据名称和接口来获取一个特定类型的对象实例,如下面的代码我们同时注册FlatFileLogger和DatabaseLogger到接口ILogger的映射,并未DatabaseLogger指定一个名称,在使用Get方法的时候就可以通过ILogger和指定的名称来获取DatabaseLogger实例:

class Program{static void Main(string[] args){IUnityContainer container = new UnityContainer();container.Register<ILogger, FlatFileLogger>();container.Register<ILogger, DatabaseLogger>("databaseLogger");ILogger logger = container.Get<ILogger>("databaseLogger");logger.Write("TerryLee");}}

再运行代码,可以看到获取到了DatabaseLogger实例:

如果我们同时同时注册FlatFileLogger和DatabaseLogger到接口ILogger的映射,并且不指定任何名称,那么直接调用Get方法将会返回后注册的组件的对象实例,如下面的代码:

class Program{static void Main(string[] args){IUnityContainer container = new UnityContainer();container.Register<ILogger, FlatFileLogger>();container.Register<ILogger, DatabaseLogger>();ILogger logger = container.Get<ILogger>();logger.Write("TerryLee");}}

运行后会返回DatabaseLogger实例:

当然我们也可以使用非泛型的Get方法来获取对象实例:

class Program{static void Main(string[] args){IUnityContainer container = new UnityContainer();container.Register<ILogger, FlatFileLogger>();ILogger logger = container.Get(typeof(ILogger)) as ILogger;logger.Write("TerryLee");}}

获取所有对象实例

除了可以获取单个对象实例之外,我们还可以一次获取容器中所有与某一接口映射的所有对象实例,但是需要依赖于在注册映射时提供的名称,如果没有指定名称,通过GetAll方法不会被获取到。

class Program{static void Main(string[] args){IUnityContainer container = new UnityContainer();container.Register<ILogger, FlatFileLogger>();container.Register<ILogger, FlatFileLogger>("flatFileLogger");container.Register<ILogger, DatabaseLogger>("DatabaseLogger");
        IEnumerable<ILogger> loggers = container.GetAll<ILogger>();foreach (ILogger logger in loggers){if (null != logger){Console.WriteLine(logger.GetType().ToString());}}}}
运行后如下,第一个没有提供名称的类型实例不会被获取到:

结束语

关于Unity的一个简单使用就到这里了,希望能够对大家有用。使用Unity简单来说分为创建容器、注册接口映射、获取对象实例这样三步,在下篇文章中,将会说到如何使用配置文件注册接口映射以及如何注册Singleton实例等内容。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
InfoQ: Microsoft Unity Dependency Injection A...
IoC容器Autofac(5) - Autofac在Asp.net MVC Filter中的应用
[IoC容器Unity]第二回:Lifetime Managers生命周期
小话设计模式原则之(1):依赖倒置原则DIP(下)
Prism学习(2)---初识Unity
Unity浅析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服