和所有的 IOC 框架一样,我们可以使用 XML 文件来配置 Unity。个人建议你使用一个单独的 XML 配置文件,因为 app.config/web.config 已经被塞入太多的东西,早已臃肿不堪。修改配置的时候既不清晰,也容易出错。
Unity.xml
test.cs
编写配置文件和读取配置的代码都不算太复杂,其自带的帮助文件也有详细的解释,我就不多废话了。
尽管有别名机制可以减少工作量和出错几率,但还是希望能提供一个图形化的管理工具,否则每次都得反反复复翻看手册,太麻烦。
Unity.xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</configSections>
<unity>
<typeAliases>
<typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
Microsoft.Practices.Unity" />
<typeAlias alias="Data" type="Learn.CUI.Data, Learn.CUI" />
<typeAlias alias="ICache" type="Learn.CUI.ICache, Learn.CUI" />
<typeAlias alias="MemoryCache" type="Learn.CUI.MemoryCache, Learn.CUI" />
<typeAlias alias="FileCache" type="Learn.CUI.FileCache, Learn.CUI" />
</typeAliases>
<containers>
<container name="global">
<types>
<type type="Data" mapTo="Data">
<lifetime type="singleton" />
</type>
<type name="memory" type="ICache" mapTo="MemoryCache" />
<type name="file" type="ICache" mapTo="FileCache">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="data" parameterType="Data">
<dependency />
</param>
<param name="s" parameterType="System.String">
<value value="Hello, World!" />
</param>
</constructor>
<property name="Data" propertyType="Data" />
<method name="Initialize">
<param name="data" parameterType="Data">
<dependency />
</param>
<param name="s" parameterType="System.String">
<value value="Who..." />
</param>
</method>
</typeConfig>
</type>
</types>
<instances>
</instances>
</container>
</containers>
</unity>
</configuration>
<configuration>
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</configSections>
<unity>
<typeAliases>
<typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
Microsoft.Practices.Unity" />
<typeAlias alias="Data" type="Learn.CUI.Data, Learn.CUI" />
<typeAlias alias="ICache" type="Learn.CUI.ICache, Learn.CUI" />
<typeAlias alias="MemoryCache" type="Learn.CUI.MemoryCache, Learn.CUI" />
<typeAlias alias="FileCache" type="Learn.CUI.FileCache, Learn.CUI" />
</typeAliases>
<containers>
<container name="global">
<types>
<type type="Data" mapTo="Data">
<lifetime type="singleton" />
</type>
<type name="memory" type="ICache" mapTo="MemoryCache" />
<type name="file" type="ICache" mapTo="FileCache">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="data" parameterType="Data">
<dependency />
</param>
<param name="s" parameterType="System.String">
<value value="Hello, World!" />
</param>
</constructor>
<property name="Data" propertyType="Data" />
<method name="Initialize">
<param name="data" parameterType="Data">
<dependency />
</param>
<param name="s" parameterType="System.String">
<value value="Who..." />
</param>
</method>
</typeConfig>
</type>
</types>
<instances>
</instances>
</container>
</containers>
</unity>
</configuration>
test.cs
public class Data { }
public interface ICache { }
public class MemoryCache : ICache { }
public class FileCache : ICache
{
[InjectionConstructor]
public FileCache(Data data, string s)
{
Console.WriteLine("--Injection Constructor--");
Console.WriteLine("data != null? {0}", data != null);
Console.WriteLine("s = {0}", s);
}
private Data data;
[Dependency]
public Data Data
{
get
{
return data;
}
set
{
data = value;
Console.WriteLine("--Injection Property--");
Console.WriteLine("this.Data != null? {0}", data != null);
}
}
[InjectionMethod]
public void Initialize(Data data, string s)
{
Console.WriteLine("--Injection Method--");
Console.WriteLine("data != null? {0}", data != null);
Console.WriteLine("s = {0}", s);
}
}
class Program
{
static void Main(string[] args)
{
var configMap = new ExeConfigurationFileMap { ExeConfigFilename = "Unity.xml" };
var configuration = ConfigurationManager.OpenMappedExeConfiguration(configMap,
ConfigurationUserLevel.None);
var section = (UnityConfigurationSection)configuration.GetSection("unity");
var container = new UnityContainer();
section.Containers["global"].Configure(container);
// --- test ---
var file = container.Resolve<ICache>("file");
}
}
public interface ICache { }
public class MemoryCache : ICache { }
public class FileCache : ICache
{
[InjectionConstructor]
public FileCache(Data data, string s)
{
Console.WriteLine("--Injection Constructor--");
Console.WriteLine("data != null? {0}", data != null);
Console.WriteLine("s = {0}", s);
}
private Data data;
[Dependency]
public Data Data
{
get
{
return data;
}
set
{
data = value;
Console.WriteLine("--Injection Property--");
Console.WriteLine("this.Data != null? {0}", data != null);
}
}
[InjectionMethod]
public void Initialize(Data data, string s)
{
Console.WriteLine("--Injection Method--");
Console.WriteLine("data != null? {0}", data != null);
Console.WriteLine("s = {0}", s);
}
}
class Program
{
static void Main(string[] args)
{
var configMap = new ExeConfigurationFileMap { ExeConfigFilename = "Unity.xml" };
var configuration = ConfigurationManager.OpenMappedExeConfiguration(configMap,
ConfigurationUserLevel.None);
var section = (UnityConfigurationSection)configuration.GetSection("unity");
var container = new UnityContainer();
section.Containers["global"].Configure(container);
// --- test ---
var file = container.Resolve<ICache>("file");
}
}
编写配置文件和读取配置的代码都不算太复杂,其自带的帮助文件也有详细的解释,我就不多废话了。
尽管有别名机制可以减少工作量和出错几率,但还是希望能提供一个图形化的管理工具,否则每次都得反反复复翻看手册,太麻烦。