Unity 1.2使用初探(2)
2009-03-15 15:15
405 查看
继续我们的Unity 1.2使用初探,在上节"Unity 1.2使用初探(1)"中,我们主要编码的形式展示了Unity的编码方式实现。下面我们讲讨论使用配置文件实现。
这里我们继续使用上节的代码:
namespace DailyPractice.UnityEx
{
public
interface
ILogService
{
void Write(string message);
}
public
class
CnsLogService: ILogService
{
#region ILogService 成员
public
void Write(string message) {
Console.WriteLine(String.Format("Cns-exception msg:{0}", message));
}
#endregion
}
public
class
DataLogService:ILogService
{
#region ILogService 成员
public
void Write(string message) {
DailyPractice.Utility.Log.AddLog(message);
}
#endregion
}
}
namespace DailyPractice.Utility
{
public
class
Log
{
public
static
void AddLog(string message) {
//insert into Log(message) values(@message)
Console.WriteLine(String.Format("Data-exception msg:{0}", message));
}
}
}
这段代码主要实现了ILogService接口,然后我们以配置文件去实现,编写如下的配置文件:
<?xml
version="1.0"
encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container
name="One">
<types>
<type
type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.DataLogService, DailyPractice.UnityEx"/>
</types>
</container>
</containers>
</unity>
</configuration>
这里我进行相关的说明,configSections配置节的是unity固定配置,通过配置文件实现Unity,先要进行此配置:
<section
name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
然后,我们在看<unity>里面的配置:
<containers>是必须元素,其内可有多container个元素,container元素就是每一个容器的配置,它有一个可选的 name属性,用于指定容器的名称。
container元素有下列子元素: types元素 ,instances元素, extensions元素。
这里主要说type元素,在文档中有这么一句:
The type element defines a type mapping for the Unity container. If you specify a name, that name is used for the type mapping. If you do not specify a name, it creates a default mapping for the specified types. You can specify a lifetime manager for each mapping. If no explicit lifetime manager is configured for a type, transient lifetime management is exercised.
大致的意思就是或type元素定义了一个指向的type,如果你指定了一个name,那么就以你指定的来mapping,否则则创建一个一个默认的mapping for the specified types,你还可以指定lifetime manager,如果你不指定,将应用transient lifetime management。
mapTo是: The actual Type object for the mapTo element in the configuration file.
所以根据以上,可以知道我们是在以 DataLogService 进行 container映射。
然后就是代码实现了:
namespace DailyPractice.UnityEx
{
public
class
UnityConfigEx
{
public
static
void Main() {
IUnityContainer myContainer = new
UnityContainer();
UnityConfigurationSection section
= (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers[0].Configure(myContainer);
ILogService myServiceInstance = myContainer.Resolve<ILogService>();
myServiceInstance.Write("oh,exception occured!");
}
}
}
执行结果为:
如果我们这样更改配置节:
<?xml
version="1.0"
encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container
name="One">
<types>
<type
type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.CnsLogService, DailyPractice.UnityEx"/>
<!--<type type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.DataLogService, DailyPractice.UnityEx"/>-->
</types>
<instances></instances>
<extensions></extensions>
</container>
</containers>
</unity>
</configuration>
执行结果为:
如果两个都配置呢?那么我们更改配置文件:
<?xml
version="1.0"
encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container
name="One">
<types>
<type
type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
name="cnslogger"
mapTo="DailyPractice.UnityEx.CnsLogService, DailyPractice.UnityEx"/>
<type
type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
name="datalogger"
mapTo="DailyPractice.UnityEx.DataLogService, DailyPractice.UnityEx"/>
</types>
<instances></instances>
<extensions></extensions>
</container>
</containers>
</unity>
</configuration>
修改程序代码:
namespace DailyPractice.UnityEx
{
public
class
UnityConfigEx
{
public
static
void Main() {
IUnityContainer myContainer = new
UnityContainer();
UnityConfigurationSection section
= (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers[0].Types[0].Configure(myContainer);
section.Containers[0].Types[1].Configure(myContainer);
IEnumerable<ILogService> myServiceInstances = myContainer.ResolveAll<ILogService>();
foreach (ILogService myServiceInstance in myServiceInstances) {
myServiceInstance.Write("haha, you have an exception 了吧!");
}
myContainer.Dispose();
}
}
}
运行结果:
这里我强调一下:配置节name="cnslogger",在刚刚开始,我没有指定了,结果报错如下
The entry ':DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx' has already been added. (D:\Project\ProjectEx\DailyPractice\UnityEx\bin\Debug\DailyPractice.UnityEx.vshost.exe.config line 22)
因为Unity有以下源码
protected
override
object GetElementKey(ConfigurationElement element)
{
UnityTypeElement typeElement = (UnityTypeElement)element;
if (typeElement.Name == null)
{
return typeElement.TypeName;
}
return typeElement.Name + ":" + typeElement.TypeName;
}
如果不指定name,那么两个type在循环时就会导致GetElementKey都返回了':DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx'结果,导致实例化UnityConfigurationSection异常。
指定name,那么这两次实例化分别是:
cnslogger:DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx
datalogger:DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx
UnityConfigurationSection即可实现正确实例化。
本节到此。
欢迎各位指教~~,谢谢
这里我们继续使用上节的代码:
namespace DailyPractice.UnityEx
{
public
interface
ILogService
{
void Write(string message);
}
public
class
CnsLogService: ILogService
{
#region ILogService 成员
public
void Write(string message) {
Console.WriteLine(String.Format("Cns-exception msg:{0}", message));
}
#endregion
}
public
class
DataLogService:ILogService
{
#region ILogService 成员
public
void Write(string message) {
DailyPractice.Utility.Log.AddLog(message);
}
#endregion
}
}
namespace DailyPractice.Utility
{
public
class
Log
{
public
static
void AddLog(string message) {
//insert into Log(message) values(@message)
Console.WriteLine(String.Format("Data-exception msg:{0}", message));
}
}
}
这段代码主要实现了ILogService接口,然后我们以配置文件去实现,编写如下的配置文件:
<?xml
version="1.0"
encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container
name="One">
<types>
<type
type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.DataLogService, DailyPractice.UnityEx"/>
</types>
</container>
</containers>
</unity>
</configuration>
这里我进行相关的说明,configSections配置节的是unity固定配置,通过配置文件实现Unity,先要进行此配置:
<section
name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
然后,我们在看<unity>里面的配置:
<containers>是必须元素,其内可有多container个元素,container元素就是每一个容器的配置,它有一个可选的 name属性,用于指定容器的名称。
container元素有下列子元素: types元素 ,instances元素, extensions元素。
这里主要说type元素,在文档中有这么一句:
The type element defines a type mapping for the Unity container. If you specify a name, that name is used for the type mapping. If you do not specify a name, it creates a default mapping for the specified types. You can specify a lifetime manager for each mapping. If no explicit lifetime manager is configured for a type, transient lifetime management is exercised.
大致的意思就是或type元素定义了一个指向的type,如果你指定了一个name,那么就以你指定的来mapping,否则则创建一个一个默认的mapping for the specified types,你还可以指定lifetime manager,如果你不指定,将应用transient lifetime management。
mapTo是: The actual Type object for the mapTo element in the configuration file.
所以根据以上,可以知道我们是在以 DataLogService 进行 container映射。
然后就是代码实现了:
namespace DailyPractice.UnityEx
{
public
class
UnityConfigEx
{
public
static
void Main() {
IUnityContainer myContainer = new
UnityContainer();
UnityConfigurationSection section
= (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers[0].Configure(myContainer);
ILogService myServiceInstance = myContainer.Resolve<ILogService>();
myServiceInstance.Write("oh,exception occured!");
}
}
}
执行结果为:
如果我们这样更改配置节:
<?xml
version="1.0"
encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container
name="One">
<types>
<type
type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.CnsLogService, DailyPractice.UnityEx"/>
<!--<type type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.DataLogService, DailyPractice.UnityEx"/>-->
</types>
<instances></instances>
<extensions></extensions>
</container>
</containers>
</unity>
</configuration>
执行结果为:
如果两个都配置呢?那么我们更改配置文件:
<?xml
version="1.0"
encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container
name="One">
<types>
<type
type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
name="cnslogger"
mapTo="DailyPractice.UnityEx.CnsLogService, DailyPractice.UnityEx"/>
<type
type="DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx"
name="datalogger"
mapTo="DailyPractice.UnityEx.DataLogService, DailyPractice.UnityEx"/>
</types>
<instances></instances>
<extensions></extensions>
</container>
</containers>
</unity>
</configuration>
修改程序代码:
namespace DailyPractice.UnityEx
{
public
class
UnityConfigEx
{
public
static
void Main() {
IUnityContainer myContainer = new
UnityContainer();
UnityConfigurationSection section
= (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers[0].Types[0].Configure(myContainer);
section.Containers[0].Types[1].Configure(myContainer);
IEnumerable<ILogService> myServiceInstances = myContainer.ResolveAll<ILogService>();
foreach (ILogService myServiceInstance in myServiceInstances) {
myServiceInstance.Write("haha, you have an exception 了吧!");
}
myContainer.Dispose();
}
}
}
运行结果:
这里我强调一下:配置节name="cnslogger",在刚刚开始,我没有指定了,结果报错如下
The entry ':DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx' has already been added. (D:\Project\ProjectEx\DailyPractice\UnityEx\bin\Debug\DailyPractice.UnityEx.vshost.exe.config line 22)
因为Unity有以下源码
protected
override
object GetElementKey(ConfigurationElement element)
{
UnityTypeElement typeElement = (UnityTypeElement)element;
if (typeElement.Name == null)
{
return typeElement.TypeName;
}
return typeElement.Name + ":" + typeElement.TypeName;
}
如果不指定name,那么两个type在循环时就会导致GetElementKey都返回了':DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx'结果,导致实例化UnityConfigurationSection异常。
指定name,那么这两次实例化分别是:
cnslogger:DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx
datalogger:DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx
UnityConfigurationSection即可实现正确实例化。
本节到此。
欢迎各位指教~~,谢谢
相关文章推荐
- Unity 1.2使用初探(1)
- Unity 1.2使用初探(2)
- Unity 1.2使用初探(1)
- AOP---Unity使用初探
- Unity GUI(uGUI)使用心得与性能总结
- ADS 1.2 使用快速入门
- Windows Mobile智能手机今日插件编程开发初探(使用C++, vs2008, Pocket PC 5.0内核)
- 复盘王者荣耀手游开发全过程,Unity引擎使用帧同步放弃状态同步
- Unity使用DLL库
- 初探JsonCpp - 编译与基本使用
- [Unity基础]xml在unity中的使用
- Unity动画,状态机的使用
- Symbian学习笔记(19) - 初探Web Services API 的使用(下)
- 1.2 KNN算法学习——使用scikit-learn中的KNN模型实现
- 在Unity中使用代码类来管理多个Panel(面板)之间的切换
- FCKEditor2.6.6使用初探
- [Unity&对象]怎么使用全局静态变量
- [Unity框架]PureMVC在unity中的简单使用
- unity_NGUI系统学习(十三)_使用脚本监听控件的值修改,取得控件的值
- [UnityUI]使用UGUI制作排行榜