快捷搜索:

[EntLib]微软企业库5.0 学习之路——第十步、使用

本日继承先容Unity,在上一篇的文章中,我先容了应用UnityContainer来注册工具之间的关系、注册已存在的工具之间的关系,同时着重先容了Unity内置的各类生命周期治理器的应用措施,本日则主要先容Unity的Register和Resolve的一些高档利用。

本篇文章将主要先容:

1、注册类型同时初始化构造函数参数并重载调用。

2、注册类型同时初始化属性参数并重载调用。

3、延迟获取工具。

4、检索检索容器中注册信息。

一、注册类型同时初始化构造函数参数并重载调用

我们在应用Unity中注册工具之间的关系时,可能工具有响应的构造函数,构造函数中必要通报响应的参数,Unity就支持这样的注册,其主要靠InjectionConstructor这个类来完成,我们首先来看下详细的类构造函数:

public YourClass(string test, MyClass my)

{

Console.WriteLine(test);

Console.WriteLine(my.ToString());

}

这个构造函数有2个参数,一个字符串和一个MyClass类工具,响应的可以应用如下代码进行注册:

//因为所注册的工具的有带有参数的构造函数,以是注册类型时必要供给响应的参数

//这边采纳InjectionConstructor这个类来实现

container.RegisterType(

new InjectionConstructor("a", new MyClass()));

Console.WriteLine("-----------默认调用输出-------------");

container.Resolve();

这样既可完成工具注册的同时对构造函数参数进行注入,此时还有别的一个需求,便是虽然在注册的时刻已经对构造函数参数进行了初始化,然则在调用的时刻我们想替换本来注册的值,这时应该怎么办?

在Unity中,已经帮我们办理了这个问题,我们可以经由过程ParameterOverride和ParameterOverrides来实现,此中ParameterOverride是针对一个参数,而ParameterOverrides是针对参数列表,有关注册参数初始化及参数重载的整个代码如下:

public static void ResolveParameter()

{

//因为所注册的工具的有带有参数的构造函数,以是注册类型时必要供给响应的参数

//这边采纳InjectionConstructor这个类来实现

container.RegisterType(

new InjectionConstructor("a", new MyClass()));

Console.WriteLine("-----------默认调用输出-------------");

container.Resolve();

Console.WriteLine("-----------重载后调用输出-------------");

//以下2种Resolve措施效果是一样的

//对付参数过多的时刻可以采纳第2种措施,假如参数仅仅只有1个可以用第1种

//container.Resolve(new ParameterOverride("test", "test"),

//new ParameterOverride("my", "new MyClass").OnType());

container.Resolve(new ParameterOverrides()

{

{"test","test"},

{"my",new MyClass()}

}.OnType());

}

此中必要留意的是:

1、在应用ParameterOverride措施来重载参数时,假如注册的参数是一个详细的工具就必要应用OnType这个扩展措施来指定对应的类型,否则会报错。

2、在应用ParameterOverrides进行重载参数时,可以应用如上面代码的要领进行指定,然则同样必要应用OnType来指定,不过这个的OnType指定的类型是注册的工具类型。

效果图如下:

可以看出,此中第一个字符串参数在重载后调用时已经发生了变动。

二、注册类型同时初始化属性并重载调用

这个初始化属性和上面的初始化参数很类似,只不过不合的是,属性的注册初始化是应用InjectionProperty,而重载属性是应用的PropertyOverride和PropertyOverrides,其应用措施也是相同的,这边就不多先容了,代码如下:

public static void ResolveProperty()

{

//注册工具关系时初始化工具的属性

container.RegisterType(

new InjectionProperty("Name", "A班"),

new InjectionProperty("Description", "A班的描述"));

Console.WriteLine("-----------默认调用输出-------------");

Console.WriteLine(container.Resolve().Name);

Console.WriteLine(container.Resolve().Description);

Console.WriteLine("-----------重载后调用输出-------------");

//以下2种写法效果是一样的,同上面的构造函数参数重载

//var myClass = container.Resolve(new PropertyOverride("Name", "重载后的A班"),

//new PropertyOverride("Description", "重载后的A班的描述"));

var myClass = container.Resolve(new PropertyOverrides()

{

{"Name","重载后的A班"},

{"Description","重载后的A班的描述"}

}.OnType());

Console.WriteLine(myClass.Name);

Console.WriteLine(myClass.Description);

}

效果图如下:

可以看到2个属性都已经被重载了。

Unity还为我们供给了一个DependencyOverride重载,其应用措施和参数重载、属性重载类似,这边就不演示了,不过必要留意的是DependencyOverride是针对所注册工具类型中所包孕的工具类型重载,例如在A类中有构造函数参数是B类,同时也有个属性依附于B类,当应用了DependencyOverride后,这个A工具本来注册的有关B类的依附将整个改变。(详细可查看示例代码中的ResolveDependency)

三、延迟获取工具

Unity还有个很不错的特点便是支持延迟获取, 其本色是经由过程事先建立一个委托,然后再调用这个委托,看下下面的代码:

public static void DeferringResolve()

{

var resolver = container.Resolve>();

//根据营业逻辑做其他工作。

//注册IClass与MyClass之间的关系

container.RegisterType();

//获取MyClass实例

var myClass = resolver();

var resolver2 = container.Resolve>>();

//根据营业逻辑做其他工作。

//注册与IClass相关的工具。

container.RegisterType("my");

container.RegisterType("your");

//获取与IClass关联的所有命名实例

var classList = resolver2();

}

这段代码演示了2个延迟获取的要领,都是经由过程将Func放入Resolve中来实现的,返回的是一委托,这样就可以在实际必要的时刻再调用这个委托:

1、第一种是事先经由过程Resolve>(); 来定义获取与IClass关联的工具的委托,然后再注册IClass与MyClass之间的关系,然后再经由过程resolver(); 来获取。

2、第二种是事先经由过程Resolve>>(); 来定义获取一个与IClass关联的命名实例列表的委托,然后调用响应的委托就可以一次性获取与IClass关联的所有命名实例。

这2种要领都很好的展示了Unity可以加倍机动的节制工具之间的注册与工具的调用。

四、检索容器中注册信息

当我们在赓续应用Unity容器的历程中,我们无意偶尔候想看一下容器中到底注册了若干工具,以及各个工具的一些信息,如:什么工具和什么工具关联、详细的注册名称和应用的生命周期治理器,这些信息都可以在容器的Registrations属性中查看到,在Unity文档中已经有个措施来查看这些信息了,代码如下:

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);

}

}

详细的注册代码如下:

public static void RegisterAll()

{

container.RegisterType("my");

container.RegisterType("your",

new ExternallyControlledLifetimeManager());

container.RegisterType("subject1");

container.RegisterType("subject2");

DisplayContainerRegistrations(container);

}

效果图如下:

可以看到,我在代码中注册的信息都已经很好的反映出来了。

同时假如想查看某个工具是否已经被注册,可以经由过程container.IsRegistered来验证,这边就不演示了。

以上便是本文的所有内容了,主要先容了Unity的Register和Resolve的一些高档利用,英文好的同伙可以直接查看Unity的官方文档。

示例代码下载:点我下载

(留意:本文示例代码是基于VS2010+Unity2.0,以是请应用VS2010打开,假如没有安装VS2010,请将相关代码复制到响应的VS中运行既可)

转自:http://www.cnblogs.com/kyo-yo/archive/2010/11/22/Learning-EntLib-Tenth-Decoupling-Your-System-Using-The-Unity-PART2-Learn-To-Use-Unity-Three.html

您可能还会对下面的文章感兴趣: