首页 » 排名链接 » 一看就懂的那种(对象容器配置配置文件注入)

一看就懂的那种(对象容器配置配置文件注入)

萌界大人物 2024-11-07 11:38:15 0

扫一扫用手机浏览

文章目录 [+]

IOC的基本概念是:不创建对象,但是描述创建它们的方式。

在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。
容器负责将这些联系在一起。

其原理是基于OO设计原则的The Hollywood Principle:Don't call us, we'll call you(别找我,我会来找你的)。

一看就懂的那种(对象容器配置配置文件注入) 排名链接
(图片来自网络侵删)

也就是说,所有的组件都是被动的(Passive),所有的组件初始化和调用都由容器负责。
组件处在一个容器当中,由容器负责管理。

简单地说,就是应用本身不负责依赖对象的创建和维护,而是将其交给一个外部容器来负责。
这样控制权就由应用转移到了外部IoC 容器,即控制权实现了所谓的反转。

比如在类型A 中需要使用类型B 的实例,而B 实例的创建并不由A 来负责,而是通过外部容器来创建。
通过IoC 的方式实现针对目标Controller 的激活具有重要的意义。

二、获取Unity

目前流行的IoC 框架,如AutoFac、Castle Windsor、Unity、Spring.NET、StructureMap和Ninject 等。

可以直接在Nuget中获取到最新版本的Unity。
我用的是Unity,不是Unity for mvc。

三、介绍Unity####

Unit是微软patterns& practices组用C#实现的轻量级、可扩展的依赖注入容器,我们可以通过代码或者XML配置文件的形式来配置对象与对象之间的关系,

在运行时直接调用Unity容器即可获取我们所需的对象,以便建立松散耦合的应用程序。

对于小型项目:用代码的方式实现即可

对于中大型项目:使用配置文件比较好

Unity既然是一种Ioc框架,那么他同样满足Ioc的共性,依赖注入划分为3 种形式,即构造器注入、属性(设置)注入和接口注入。

四、Unity API(部分)

UnityContainer.RegisterType<ITFrom,TTO>();

UnityContainer.RegisterType< ITFrom, TTO>("keyName");

IEnumerable<T> databases = UnityContainer.ResolveAll<T>();

IT instance = UnityContainer.Resolve<IT>();

T instance = UnityContainer.Resolve<T>("keyName");

UnitContainer.RegisterInstance<T>("keyName",new T());

UnityContainer.BuildUp(existingInstance);

IUnityContainer childContainer1 = parentContainer.CreateChildContainer();

五、使用Untiy

如果是使用的NuGut安装的Unity库,那么在项目中将会自动添加引用

Microsoft.Practices.Unity.dll

Microsoft.Practices.Unity.Configuration.dll

Microsoft.Practices.Unity.RegistrationByConvention.dll

1、用编程方式实现注入

使用Unity来管理对象与对象之间的关系可以分为以下几步:

A、创建一个UnityContainer对象

B、通过UnityContainer对象的RegisterType方法来注册对象与对象之间的关系

C、通过UnityContainer对象的Resolve方法来获取指定对象关联的对象

注入代码如下:

/// <summary> /// 商品 /// </summary> public interface IProduct { string ClassName { get; set; } string ShowInfo(); } /// <summary> /// 牛奶 /// </summary> public class Milk : IProduct { public string ClassName { get; set; } public void ShowInfo() { return string.Format("牛奶:{0}", ClassName); } } /// <summary> /// 糖 /// </summary> public class Sugar : IProduct { public string ClassName { get; set; } public void ShowInfo() { return string.Format("糖:{0}", ClassName); } }/// <summary> /// 代码注入 /// </summary> public string ContainerCode() { IUnityContainer container = new UnityContainer(); container.RegisterType<IProduct, Milk>(); //默认注册(无命名),如果后面还有默认注册会覆盖前面的 container.RegisterType<IProduct, Sugar>("Sugar"); //命名注册 IProduct _product = container.Resolve<IProduct>(); //解析默认对象 _product.ClassName = _product.GetType().ToString(); string str1 = _product.ShowInfo();<br> IProduct _sugar = container.Resolve<IProduct>("Sugar"); //指定命名解析对象 _sugar.ClassName = _sugar.GetType().ToString(); string str2 = _sugar.ShowInfo();<br><br>       StringBuilder strs = new StringBuilder();<br>       strs.Append(str1);<br>       strs.Append(str2);<br> IEnumerable<IProduct> classList = container.ResolveAll<IProduct>(); //获取容器中所有IProduct的注册的已命名对象 foreach (var item in classList) { item.ClassName = item.GetType().ToString(); strs.Append(item.ShowInfo()); }return strs.ToString(); }</pre>结果:牛奶:UnityTest.Milk 糖:UnityTest.Sugar 糖:UnityTest.Sugar

2、配置文件方式

通过配置文件配置Unity信息需要有以下几个步骤:

A、在配置文件<configSections> 配置节下注册名为unity的section

B、在<configuration> 配置节下添加Unity配置信息

C、在代码中读取配置信息,并将配置载入到UnityContainer中

配置文件内容如下:

<configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> <!--声明容器--> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/> </configSections> <unity> <!--定义类型别名--> <aliases> <add alias="IProduct" type="UnityTest.IProduct,UnityTest" /> <add alias="Milk" type="UnityTest.Milk,UnityTest" /> <add alias="Sugar" type="UnityTest.Sugar,UnityTest" /> </aliases> <!--容器--> <container name="MyContainer"> <!--映射关系--> <register type="IProduct" mapTo="Milk"></register> <register type="IProduct" mapTo="Sugar" name="Sugar"></register> </container> </unity></pre>添加引用:using System.Configuration;using Microsoft.Practices.Unity.Configuration;<pre class="code" data-lang="javascript" style="box-sizing: border-box; margin: 0px; padding: 0px; white-space: pre-wrap;">/// <summary> /// 配置文件注入 /// </summary> public string ContainerConfiguration() { //加载容器配置 IUnityContainer container = new UnityContainer(); container.LoadConfiguration("MyContainer"); UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");//获取指定名称的配置节 section.Configure(container, "MyContainer");//获取特定配置节下已命名的配置节<container name='MyContainer'>下的配置信息 IProduct classInfo = container.Resolve<IProduct>("Sugar"); classInfo.ClassName = classInfo.GetType().ToString(); return classInfo.ShowInfo(); }</pre>结果:糖:UnityTest.Sugar

如果系统比较庞大,那么对象之间的依赖关系可能就会很复杂,最终导致配置文件变得很大,所以我们需要将Unity的配置信息从App.config或web.config中分离出来到某一个单独的配置文件中,比如Unity.config,实现方式可以参考如下代码:

<?xml version="1.0" encoding="utf-8"?><configuration> <system.web> <compilation debug="true" targetFramework="4.5.2" /> <httpRuntime targetFramework="4.5.2" /> </system.web> <configSections> <!--声明容器--> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/> </configSections> <unity> <!--定义类型别名--> <aliases> <add alias="IProduct" type="UnityTest.IProduct,UnityTest" /> <add alias="Milk" type="UnityTest.Milk,UnityTest" /> <add alias="Sugar" type="UnityTest.Sugar,UnityTest" /> </aliases> <!--容器--> <container name="MyContainer"> <!--映射关系--> <register type="IProduct" mapTo="Milk"></register> <register type="IProduct" mapTo="Sugar" name="Sugar"></register> </container> </unity></configuration></pre>

注册代码:

/// <summary> /// 配置文件注入 /// </summary> public string ContainerConfiguration2() { IUnityContainer container = new UnityContainer(); string configFile = "Unity.config"; var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile }; //从config文件中读取配置信息 Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); //获取指定名称的配置节 UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); //载入名称为FirstClass 的container节点 container.LoadConfiguration(section, "MyContainer"); IProduct classInfo = container.Resolve<IProduct>("Sugar"); classInfo.ClassName = classInfo.GetType().ToString(); return classInfo.ShowInfo(); }</pre>结果:糖:UnityTest.Sugar

标签:

相关文章

一看就懂的那种(对象容器配置配置文件注入)

IOC的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务...

排名链接 2024-11-07 阅读 评论0