- 浏览: 178717 次
- 性别:
- 来自: 福州
文章分类
最新评论
-
别样人生:
thank you
Linux 入门教程 -
johlon:
能不能发个Demo看看,谢谢!
Gson——循环引用的解决方案 -
strong_fee:
你可以从后台返回dept对象,这个对象里边包含emp集合。
Gson——循环引用的解决方案 -
遇见的秘密花园:
可不可以加我QQ呀 282632256 我想问你一些问题。 ...
Spring总结 -
遇见的秘密花园:
我没怎么看懂。。。我现在在做S2H集成的时候。遇到一个问题。d ...
Gson——循环引用的解决方案
Reference:
使用Unity解耦你的系统—PART2——了解Unity的使用方法(1)
一、初始化UnityContainer
-
- 使用API
- 使用配置文件
IUnityContainer container = new UnityContainer()
// Register 映射。
<configSections> <section name=”unity” type=”Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration”/> </configSections>
<unity xmlns=”http://schemas.microsoft.com/practices/2010/unity”>
<alias alias=”IClass” type=”UnityStudyConsole.IDemo.IClass, UnityStudyConsole” />
<container name=”First”>
<register type=”IClass” mapTo=”MyClass” />
</container>
</unity>IUnityContainer container = new UnityContainer();
// 使用LoadConfiguration默认使用unity section加载unity(无名字)节点。
container.LoadConfiguration();
// 获取section,加载有名字的unity配置。
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection(“unity”);
container.LoadConfiguration(section, “First”);参考:
二、注册
-
- 使用RegisterType
container .RegisterType<IStocksTickerView, StocksTickerForm>() .RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>();
注:使用RegisterType注册的默认生命周期为transient lifetime(每次使用Resolve或者ResolveAll或者属性注入的时候都实例化一个新实例)。
- 使用RegisterInstance
- 属性注入(方法与构造函数注入类似)
- 【使用标注】在属性前加[Dependency]标注,如:
[Dependency]
public ILogger Logger
{
get { return logger; }
set { logger = value; }
}对于实体类,解析的时候可以使用默认的规则解析。对于接口活虚类,需要注册。如:
- 【使用API】使用API进行属性注入
RegisterType<ILogger, ConsoleLogger>();
使用带有名字的的属性注入,如:
[Dependency(“UI”)]
public ILogger Logger
{
get { return logger; }
set { logger = value; }
}注册带有名字的Logger,如:
RegisterType<ILogger, TraceSourceLogger>(“UI”);
注册不带名字的属性
RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>( new InjectionProperty(“Logger”))
注:其中Logger为MoneyCentralStockQuoteService类中的一个类型为ILogger的属性。
注入带有名字的属性:
RegisterType<StocksTickerPresenter>( new InjectionProperty(“Logger”, new ResolvedParameter<ILogger>(“UI”)));
注:其中new InjectionProperty第二参数是指示要解析一个名字为“UI”的ILogger。
注册多个属性:
//注册对象关系时初始化对象的属性 container.RegisterType<IClass, MyClass>( new InjectionProperty("Name", "A班"), new InjectionProperty("Description", "A班的描述"));
重载调用:
//var myClass = container.Resolve<IClass>(new PropertyOverride
// ("Name", "重载后的A班"), // new PropertyOverride("Description", "重载后的A班的描述")); var myClass = container.Resolve<IClass>(new PropertyOverrides() { {"Name","重载后的A班"}, {"Description","重载后的A班的描述"} }.OnType<MyClass>());
注意:The PropertyOverride is not limited to a single type,
so it will apply to all resolved objects with a “Logger” property.
参考:本篇中的构造函数注入
- 【使用标注】在属性前加[Dependency]标注,如:
- 构造函数注入
- 【使用标注】如果一个类有多个构造函数,则需要在使用的构造参数前加标注:
[InjectionConstructor]
- 【使用API】 注入构造函数
RegisterType<ILogger, TraceSourceLogger>( “UI”, new InjectionConstructor(“UI”))
注:其中第一个参数“UI”为ILogger, TraceSourceLogger的映射名,第二个参数new InjectionConstructor(“UI”)为构造函数传入一个字符串类型的参数“UI”。如此,TraceSourceLogger将调用一个带有string类型的构造函数。
使用这个API注入比用“InjectionConstructor”标注的构造函数的优先级别更高。
如:
container.RegisterType<IClass, YourClass>( new InjectionConstructor("my", new MyClass())); container.Resolve<IClass>();
在调用的时候我们想更换原先注册的值,可以通过ParameterOverride和ParameterOverrides
来实现,其中ParameterOverride是针对一个参数,而ParameterOverrides是针对参数列表:
// 在使用ParameterOverrides进行重载参数时,
// 可以使用如上面代码的方式进行指定,但是同样需要使用OnType来指定,
// 不过这个的OnType指定的类型是注册的对象类型。
container.Resolve<IClass>(new ParameterOverrides() { {"test","test"}, {"my",new MyClass()} }.OnType<YourClass>());
// 在使用ParameterOverride方法来重载参数时,如果注册的参数是一个
// 具体的对象就需要使用OnType这个扩展方法来指定对应的类型,否则会报错。
container.Resolve<IClass>(new ParameterOverride("test", "test"),
new ParameterOverride("my", "new MyClass").OnType<MyClass>());
- 【使用标注】如果一个类有多个构造函数,则需要在使用的构造参数前加标注:
- DependencyOverride
- 注册泛型
- 使用API
- 使用配置文件
container .RegisterType( typeof(IRepository<>), typeof(ValidatingRepository<>), “validating”);
注意:open generic types cannot be used as generic type arguments。可以在开闭泛型之间建立映射,也可以在闭映射和非泛型之间建立映射,如:
RegisterType<IValidator<StockQuote>, RandomStockQuoteValidator>();
使用overrides解析泛型:
StocksTickerPresenter presenter = container.Resolve<StocksTickerPresenter>( new ParameterOverride( “repository”, new ResolvedParameter<IRepository<StockQuote>>(“validating”)) .OnType<StocksTickerPresenter>());
闭泛型
<register type=”IRepository[StockQuote]” mapTo=”DebugRepository[StockQuote]“/>
开泛型
<register type=”IRepository[]” mapTo=”DebugRepository[]“/>
例:
<register type=”IRepository[]” mapTo=”DebugRepository[]“/>
public StocksTickerPresenter( IStocksTickerView view, IStockQuoteService stockQuoteService, IRepository<StockQuote> repository) { … }
解析IRepository<StockQuote>过程:首先查找是否有相应的闭泛型,如果有,则进一步解析构造函数,…;如果没有,则查找开泛型,IRepository<>被找到,此时,开泛型DebugRepository<>被使用,StockQuote被传作泛型参数,解析完毕。
- 数组注入
// 注册实例,“UI”为实例名。
RegisterInstance(new TraceSource(“UI”, SourceLevels.All));
// 注册接口与实例的映射(MySingleton为映射名)
myContainer.RegisterInstance<IMyObject>(“MySingleton”, MyRealObject);
// 注册带有生命周期的接口与实例的映射。
myContainer.RegisterInstance<IMyObject>(“MySingleton”, MyRealObject, new ContainerControlledLifetimeManager());
注:使用RegisterInstance注册的实例的生命周期为ContainerControlledLifetimeManager;使用该方法无法为实例制定TransientLifetimeManager生命周期,否则会产生异常。
Unity还为我们提供了一个DependencyOverride重载,其使用方法和参数重载、属性重载类似,这边就不演示了,不过需要注意的是DependencyOverride是针对所注册对象类型中所包含的对象类型重载,例如在A类中有构造函数参数是B类,同时也有个属性依赖于B类,当使用了DependencyOverride后,这个A对象原先注册的有关B类的依赖将全部改变。
CompositeLogger的构造函数为:
public CompositeLogger(ILogger[] loggers)
{
this.loggers = (IEnumerable<ILogger>)loggers.Clone();
}注册方法为:
RegisterType<ILogger, CompositeLogger>( “composite”, new InjectionConstructor( new ResolvedArrayParameter<ILogger>( typeof(ILogger), new ResolvedParameter<ILogger>(“UI”))));
其中:第一个参数typeof(ILogger是new ResolvedParameter<ILogger>())的简写。
注意:当解析Array时,只有有名字的实例会被包含进来。
- 使用RegisterType
三、解析
-
- 语法
- 延迟获取对象
StocksTickerPresenter presenter = container.Resolve<StocksTickerPresenter>();
注:如果StocksTickerPresenter的构造函数有参数,则需要先注册参数。
public static void DeferringResolve() { var resolver = container.Resolve<Func<IClass>>(); //注册IClass与MyClass之间的关系 container.RegisterType<IClass, MyClass>(); //获取MyClass实例 var myClass = resolver(); var resolver2 = container.Resolve<Func<IEnumerable<IClass>>>(); //注册与IClass相关的对象。 container.RegisterType<IClass, MyClass>("my"); container.RegisterType<IClass, YourClass>("your"); //获取与IClass关联的所有命名实例 var classList = resolver2(); }
-
- 检索容器中注册信息
public static void DisplayContainerRegistrations(
IUnityContainer theContainer) { string regName, regType, mapTo, lifetime; Console.WriteLine("容器中 {0} 个注册信息:", theContainer.Registrations.Count()); foreach (ContainerRegistration item in theContainer.Registrations) { regType = item.RegisteredType.Name; mapTo = item.MappedToType.Name; regName = item.Name ?? "[默认]"; lifetime = item.LifetimeManagerType.Name; if (mapTo != regType) { mapTo = " -> " + mapTo; } else { mapTo = string.Empty; } lifetime = lifetime.Substring(0, lifetime.Length -
"生命周期管理器".Length); Console.WriteLine("+ {0}{1} '{2}' {3}", regType, mapTo,
regName, lifetime); } }
四、生命周期
-
- 使用生命周期
- 使用API
- 使用配置文件
RegisterType<ILogger, TraceSourceLogger>( “UI”, new ContainerControlledLifetimeManager(), new InjectionConstructor(“UI”))
<register type="IClass" mapTo="MyClass"> <lifetime type="transient" /> <!--<lifetime type="SessionLifetimeManager" value="Session#1" typeConverter="SessionLifetimeConverter" />
--> </register><br>
-
生命周期的类型
-
ContainerControlledLifetimeManager:维护一个对象实例的强引用,每次调用的时候都会返回同一对象。
- ExternallyControlledLifetimeManager:作用类似于singleton,但是当实例没有被引用的时候,垃圾回收期将回收这个实例。 如果被GC回收后再次调用Resolve方法将会重新创建新的对象。调用GC的代码如下:
- PerThreadLifetimeManager:每个线程拥有一个实例。对于一个线程来说,作用类似于singleton。 一般来说不建议在使用RegisterInstance对已存在的对象注册关系时使用PerThreadLifetimeManager,因为此时的对象已经在一个线程内创建了,如果再使用这个生命周期管理器,将无法保证其正确调用。
- TransientLifetimeManager:每次调用Resolve or ResolveAll或者属性注入的时候都实例化一个新实例时创建新实例。
-
HierarchicalLifetimeManager:类似于ContainerControlledLifetimeManager,不同之处在于父容器和子容器维护各自的生命周期。也就是说,用子容器注册一个映射之后,用父容器和子容器解析解析出来的实例是不同的。Unity这种分级容器的好处就在于我们可以对于有不同生命周期的对象放在不同的容器中,如果一个子容器被释放,不会影响到其它子容器中的对象,但是如果根节点处父容器释放后,所有的子容器都将被释放。
<register type="IClass" mapTo="MyClass" name="hl"> <lifetime type="hierarchical"> </register>
- PerResolveLifetimeManager:类似于TransientLifetimeManager,区别在于在第一调用的时候会创建一个新的对象,而再次通过循环引用访问到的时候就会返回先前创建的对象实例。如:
GC.Collect();
配置文件如下:
<register type=”IClass” mapTo=”MyClass” name=”ccl”>
<lifetime type=”external” />
</register><register type=”IClass” mapTo=”MyClass” name=”ccl”>
<lifetime type=”perthread” />
</register><register type=”IClass” mapTo=”MyClass” name=”ccl”>
<lifetime type=”transient” />
</register> -
ContainerControlledLifetimeManager:维护一个对象实例的强引用,每次调用的时候都会返回同一对象。
- 使用生命周期
{ [Dependency] public IPresenter Presenter { get; set; } } public class MockPresenter : IPresenter { [Dependency] public IView View { get; set; } } 解析IView得到的实例Presenter 中的View与第一次解析IView的实例为同一个。
发表评论
-
.Net RDLC报表
2012-04-20 00:26 8591一、创建报表 可以通过Report或者Report Wiza ... -
Links About Code First
2012-04-19 22:15 1597一、Workthrough EF 4.1 Code ... -
HID通信
2012-02-22 20:18 0尽情期待...... -
基于.Net的ActiveX插件开发
2012-02-07 00:00 2485一、编写控件类 一般而言,一个控件只提供一个暴露给COM的类 ... -
精彩技术博客
2009-04-29 13:08 10411. C/C++ 精彩博客 九 ... -
Oracle表更新操作
2009-04-09 23:15 267一. 关系数据库Company: 工作人员: EM ... -
Oracle基本语法_SQL_PLUS基本命令
2009-03-27 22:52 369一. 登陆方法: 从DOS:cmdàmysql (用户名 ... -
几本Linux书籍
2008-11-22 17:04 16801.Advanced_Linux_Programming 2. ... -
班级演讲(网络编程)
2008-11-04 14:07 1302首先跟大家申明一下,我以下所讲的内容都是我自己凭自己的想法 ... -
Beginning Linux(英文版)
2008-11-01 21:59 1374这段时间开始看这本书了《Beginning Linux® ... -
Linux 入门教程
2008-10-19 22:59 1850这是我们老师给我们上课用的课间,觉得对Linux入门很不错。 ... -
Mysql中文问题解决方案
2008-09-09 12:47 1010阅读过不少关于mysql的编码设置和乱码问题的一些文章,经过再 ...
相关推荐
在Unity游戏开发中,通常在启动应用程序时会播放一段Unity的开场Logo动画,这是Unity引擎的默认设置。这个Logo展示了Unity的技术和品牌,但有时开发者可能希望去除这个Logo以提供更定制化的用户体验或者满足特定的...
Figma Converter for Unity适用Unity的Figma转换器Unity游戏开发插件资源unitypackage 版本3.1.0 支持Unity版本2021.3.0或更高 一种自动将布局从 Figma 转换为 Unity Canvas 的资源。 描述 有了这个资产,您可以一键...
Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。 unity多人RPG游戏源码uMMORPG 2D 1.3,...
Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。 Unity精品农场经营游戏源码unity完整...
最新Unity插件SteamVR Plugin steamvr_2_8_0.unitypackage最新Unity插件SteamVR Plugin steamvr_2_8_0.unitypackage最新Unity插件SteamVR Plugin steamvr_2_8_0.unitypackage最新Unity插件SteamVR Plugin steamvr_2_...
Unity游戏代码 ,Unity经典游戏源码 , Unity休闲游戏源码, Unity容易上手的游戏源码,Unity小游戏源码,Unity新手练习源码,Unity个人开发源码,Unity优秀项目,Unity商店优秀作品。 如果运行或测试时遇到问题,可随时联系...
Unity跑酷游戏源码,Utimate 3.0 unity3d精品资源 Infinite Runner UtimateUnity精品小游戏源码 , Unity完整项目源码 是Unitypackage包 , 新建空项目直接导入到项目里面就可以运行了,无需其他操作,适合二次开发和学习...
《AE2Unity:After Effect 到 Unity 的动画迁移技术详解》 在数字内容创作领域,Adobe After Effects(简称AE)和Unity是两个重要的工具。AE主要用于视觉特效、动态图形和动画制作,而Unity则是一个强大的游戏引擎...
unity五子棋游戏demo源码 Unity精品小游戏源码 , Unity完整项目源码 是Unitypackage包 , 新建空项目直接导入到项目里面就可以运行了,无需其他操作,适合二次开发和学习使用,都是经典游戏,需要其他游戏源码包可以看我...
Unity是一款强大的跨平台游戏开发引擎,它被广泛用于创建2D和3D的互动内容,包括游戏、模拟器以及各种可视化应用。"DatePicker for UnityUI" 是一个专门为Unity设计的日期选择组件,它使得在Unity界面中集成日期选择...
unity解密游戏系统Adventure Creator Unity商店的精品资源 适合二次开发和学习使用 是个Unitypackage包 , 创建个空项目直接导入就行了 如果打开报错请切换编译器版本或者下载最新编译器就行了 unity解密游戏系统...
"Unity2018去除UnityLogo工具"是一个专为Unity2018版本设计的小型应用程序,旨在帮助用户在构建游戏或应用时移除Unity启动时的公司标识(即Unity Logo)。这可能对于那些希望提供更个性化用户体验,或者需要遵守特定...
Azure Kinect Examples for Unity.unitypackage unity 商城kinect Azure DK的unity例程 这是一组 Azure Kinect(又名 ‘Kinect for Azure’,K4A)示例,其中采用了几个主要脚本,已分组放在一个文件夹中。该资源包...
### Kinect for Unity SDK v2.9.unitypackage #### 知识点一:Kinect SDK 2.0 for Unity **Kinect SDK 2.0 for Unity** 是一个专为Unity游戏引擎设计的插件,它允许开发者在Unity环境中轻松地访问Kinect设备的各项...
UnityHub是一款由Unity Technologies开发的官方工具,专为管理和安装Unity的不同版本而设计。这款工具使得开发者能够方便地在同一个环境中切换不同的Unity编辑器版本,无论是为了兼容项目需求,还是进行版本间的比较...
Unity、3D、特效、刀光、卡通、RPG、VFX、战斗、战斗光影、Unity3D、动作特效、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、Unity3D、...
unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码unity武侠角色扮演游戏源码...
Unity glTF 2.0 Exporter 是一个专为Unity开发者设计的插件,它允许用户将Unity场景中的3D模型对象导出为glTF 2.0格式的文件。glTF,全称“Graphics Language Transmission Format”,是一种开放标准的3D模型格式,...
Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用Unity插件源码,资源完整,真实可用...
UnityHub是一款由Unity Technologies开发的官方工具,专为管理和安装Unity编辑器的不同版本而设计。在Mac平台上,UnityHub 2.4版本是该软件的一个旧版本,它提供了对Unity开发环境的便捷管理功能,尤其是对于那些...