接口以及实现类
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public interface ISayHello
{
void SayHello();
}
public class FatherSayHello : ISayHello
{
public void SayHello()
{
Console.WriteLine("Father:Hello World!");
}
}
public class MotherSayHello : ISayHello
{
public void SayHello()
{
Console.WriteLine("Mother:Hello World!");
}
}
public class ChildSayHello : ISayHello
{
public int ChildCount { get; set; }
public ChildSayHello()
: this(1) { }
public ChildSayHello(int count)
{
ChildCount = count;
}
public void SayHello()
{
for (int i = 0; i < ChildCount; i++)
{
Console.WriteLine(string.Format("Child{0}:Hello World!", i));
}
}
}
public class FamilySayHello : ISayHello
{
public ISayHello[] FamilyMembers { get; set; }
public void SayHello()
{
if (FamilyMembers != null)
{
foreach (var member in FamilyMembers)
member.SayHello();
}
}
}
在程序中主要对FamilySayHello的Family属性和ChildSayHello类的构造函数进行注入。首先,创建一个Unity容器的实例IUnityContainer container =new UnityContainer();然后,使用运行时或设计时方式对容器进行配置。
l 运行时配置:
container.RegisterType<ISayHello,FatherSayHello>("father");
container.RegisterType<ISayHello,MotherSayHello>("mother");
container.RegisterType<ISayHello,ChildSayHello>("child",new InjectionConstructor(2));
container.RegisterType<ISayHello,FamilySayHello>(newInjectionProperty("FamilyMembers",typeof(ISayHello[])));
在这里分别注册了father、mother以及child三个ISayHello接口的类型,其中对ChildSayHello类型进行了构造函数注入,传入了一个Int型2,与参数count对应;对FamilySayHello类型进行了属性注入,属性的名字为“FamilyMembers”,类型为ISayHello数组,当从容器中获取FamilySayHello类的实例时,Unity容器会使用ResolveAll<>()方法解析对应的类型,获取所有在Unity容器中注册了的ISayHello类的有名字的实例,并设置到“FamilyMembers”属性上。
Tip:特别要注意的是,ResolveAll方法只返回对应类型的所有设置了name属性的实例,所以这里不会把FamilySayHello实例再次传入,避免了构造FamilySayHello实例时的死循环。
l 设计时配置:
<?xmlversion="1.0"encoding="utf-8" ?>
<configuration>
<configSections>
<sectionname="unity"type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unityxmlns="http://schemas.microsoft.com/practices/2010/unity">
<aliasalias="ISayHello"type="HelloWorld.ISayHello, HelloWorld" />
<namespacename="HelloWorld" />
<assemblyname="HelloWorld" />
<container>
<registertype="ISayHello"mapTo="FamilySayHello">
<propertyname="FamilyMembers"dependencyType="HelloWorld.ISayHello[],HelloWorld"/>
</register>
<registertype="ISayHello"name="father"mapTo="HelloWorld.FatherSayHello,HelloWorld" />
<registertype="ISayHello"name="mother"mapTo="MotherSayHello" />
<registertype="ISayHello"name="child"mapTo="ChildSayHello" >
<constructor>
<paramname="count"value="2"/>
</constructor>
</register>
</container>
</unity>
</configuration>
配置文件中的信息基本与设计时的API所对应,所不同的是这里多了alias、namespace、assembly三个节点。这三个节点是为了容器在运行时查找对应名字的实例时使用的,其中alias表示一个类型的别名,namespace和assembly分别表示了类型所在的名字空间和程序集。这样当我们配置大量类型映射的时候,就不用一个个写出类型的FullName,从而节省大量的配置时间。
Tip:使用名字空间和程序集查找会产生一定程度的性能损失,所以如果应用程序对性能要求很高的话,还是推荐写类型的FullName。
最后,从Unity容器中获取FamilySayHello类型的实例,并调用SayHello方法,结果如下:
Father:Hello World!
Mother:Hello World!
Child0:Hello World!
Child1:Hello World!
请按任意键继续. . .
附:Unity程序集下载
源码下载(源码中的Unity程序集引用请自行下载上面的程序集修复)