日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Castle实践9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility)

發(fā)布時(shí)間:2024/8/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Castle实践9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在“Castle實(shí)踐8”介紹了A#的使用方法,那么A#如何和Castle IOC容器結(jié)合起來使用呢?在Castle的官方falicicies庫中,提供了AspectSharp Facility來讓我們可以很簡單在IOC中使用A#。我把使用方法放在最后,題目說了是要全面剖析這個(gè)facility的原理,借助這次分析讓我們對Castle IOC中的Falicity編寫有更深的了解。

??????? 編寫一個(gè)facility之前,最重要的就是要明確這個(gè)falicity的目的。通過“實(shí)踐8”知道,要使用一個(gè)aop過的對象,需要調(diào)用engine.WrapClass或者engine.WrapInterface來對目的對象包裝,那么得出這個(gè)facility的目的就是:當(dāng)用戶向IOC容器請求組件的時(shí)候,根據(jù)aop的配置自動包裝組件再交給客戶使用。

??????? 明白了需求,那么就開始分析吧:
protected?override?void?Init()
{
????
if?(FacilityConfig?==?null)?return;

????
//?第一步
????RegisterAspectEngine();
????
//?第二步
????RegisterInterceptor();

????
//?第三步
????Kernel.ProxyFactory?=?new?AopProxyFactory();

????
//?第四步
????_engine?=?(AspectEngine)?Kernel[?typeof(AspectEngine)?];

????
//?第五步:向IOC里面加入任何組件的時(shí)候,OnComponentRegistered會回調(diào)
????Kernel.ComponentRegistered?+=?new?ComponentDataDelegate(OnComponentRegistered);
}


第一步:
private?void?RegisterAspectEngine()
{
????
//?獲取當(dāng)前facility的配置,相當(dāng)于獲取了a#的配置
????String?contents?=?FacilityConfig.Value;

????
//?創(chuàng)建a#的builder
????AspectEngineBuilder?builder?=?new?AspectLanguageEngineBuilder(contents);

????ComponentModel?model?
=?
????????
new?ComponentModel("aspectsharp.engine",?
????????????
typeof(AspectEngine),?typeof(AspectEngine));
????
????
//?a#的builder作為擴(kuò)張屬性
????model.ExtendedProperties.Add("builder",?builder);
????
//?engine激活的時(shí)候執(zhí)行AspectEngineActivator
????model.CustomComponentActivator?=?typeof(AspectEngineActivator);

????
//?把a(bǔ)#?engine作為組件加入ioc中
????Kernel.AddCustomComponent(?model?);
}


第二步:
private?void?RegisterInterceptor()
{
????
//?講AopInterceptor加入IOC中
????Kernel.AddComponent(?"aspectsharp.interceptor",?typeof(AopInterceptor)?);
}


第三步:注冊ioc的proxy工廠 ///?<summary>
///?Specialization?of?<see?cref="Castle.Windsor.Proxy.DefaultProxyFactory"/>
///?that?checks?for?aspects?in?the?model?and?potential?mixins.
///?</summary>
public?class?AopProxyFactory?:?DefaultProxyFactory
{
protected?override?void?CustomizeContext(GeneratorContext?context,?IKernel?kernel,?
????ComponentModel?model,?
object[]?arguments)
{
????
//?獲取a#的配置
????AspectDefinition?aspect?=?(AspectDefinition)?model.ExtendedProperties["aop.aspect"];

????
if?(aspect?==?null)?return;

????
//?得到所有mixin
????MixinDefinitionCollection?mixins?=?aspect.Mixins;

????
foreach(MixinDefinition?definition?in?mixins)
????{
????????Type?mixinType?
=?definition.TypeReference.ResolvedType;
????????
????????
try
????????{
????????????
//?創(chuàng)建一個(gè)minix對象并交給dynamicproxy,dynamicproxy產(chǎn)生proxy的時(shí)候會用到
????????????context.AddMixinInstance(?Activator.CreateInstance(?mixinType?)?);
????????}
????????
catch(Exception?e)
????????{
????????????
throw?new?ApplicationException("Could?not?instantiate?mixin?"?+?mixinType.FullName,?e);
????????}
????}
}

protected?override?void?CustomizeProxy(object?proxy,?GeneratorContext?context,?IKernel?kernel,?ComponentModel?model)
{
????
//?獲取在上面的CustomizeContext函數(shù)中創(chuàng)建的mixin對象
????object[]?mixins?=?context.MixinsAsArray();

????
//?所有實(shí)現(xiàn)了IProxyAware的mixin對象,都會把實(shí)際的代理set到里面交給客戶處理
????
//在“Castle實(shí)踐8”中的SecurityMixin就是實(shí)現(xiàn)了IProxyAware的,在SecurityMixin類
????
//上下文中可以任意使用proxy,這下明白了吧。
????for(int?i=0;?i?<?mixins.Length;?i++)
????{
????????
object?mixin?=?mixins[i];
????????
????????
if?(mixin?is?IProxyAware)
????????{
????????????(mixin?
as?IProxyAware).SetProxy(proxy);
????????}
????}
}


第四步:激活a# engine,導(dǎo)致AspectEngineActivator執(zhí)行 protected?override?object?InternalCreate()
{
????
//?獲取a#的builder
????AspectEngineBuilder?builder?=?(AspectEngineBuilder)?
????????
base.Model.ExtendedProperties["builder"];

????System.Diagnostics.Debug.Assert(?builder?
!=?null?);

????
//?創(chuàng)建engine
????return?builder.Build();
}


第五步:向IOC里面加入任何組件的時(shí)候,OnComponentRegistered會回調(diào) private?void?OnComponentRegistered(String?key,?IHandler?handler)
{
????
//?檢查a#配置中是否包含組件的“切面”
????
//就是當(dāng)前加入的這個(gè)組件是否需要aop(怎么說呢??表達(dá)不太清晰,大家應(yīng)該明白吧。請?jiān)弤~)
????AspectDefinition[]?aspects?=?
????????_engine.AspectMatcher.Match(?handler.ComponentModel.Implementation,?
????????_engine.Configuration.Aspects?);

????
if?(aspects.Length?!=?0)
????{
????????
//?如果組件需要aop,則合并配置中對此組件的切面定義
????????
//并將定義加入到組件的擴(kuò)張屬性中
????????handler.ComponentModel.ExtendedProperties["aop.aspect"]?=?Union(aspects);

????????
//?向組件加入攔截器
????????
//當(dāng)向ioc請求組件對象的時(shí)候,攔截器的作用就是根據(jù)上面的定義來產(chǎn)生一個(gè)組件的proxy
????????handler.ComponentModel.Interceptors.Add(?
????????????
new?InterceptorReference(?typeof(AopInterceptor)?)?);
????}
}

private?AspectDefinition?Union(AspectDefinition[]?aspects)
{
????
//?這里作用是合并對組件的“切面”配置內(nèi)容
????
//但作者todo了,未完成?

????
if?(aspects.Length?==?1)
????{
????????
return?aspects[0];
????}

????
//?TODO:?Merge?aspects

????
return?aspects[0];
}


???????? 這時(shí)候回頭來看看,我們的目的是自動包裝,上面的代碼中沒有調(diào)用A# engine的WrapClass和WrapInterface的,其實(shí)兩個(gè)wrap做的是調(diào)用DefaultProxyFactory來產(chǎn)生代理的,這里給AopProxyFactory代替了。而真正請求一個(gè)組件的時(shí)候,產(chǎn)生代理的工作都是在AopInterceptor中處理的。


///?<summary>
///?Summary?description?for?AopInterceptor.
///?</summary>
[Transient]
public?class?AopInterceptor?:?IMethodInterceptor,?IOnBehalfAware
{
????
private?IKernel?_kernel;
????
private?AspectEngine?_engine;
????
private?IInvocationDispatcher?_dispatcher;

????
public?AopInterceptor(AspectEngine?engine,?IKernel?kernel)
????{
????????_engine?
=?engine;
????????_kernel?
=?kernel;
????}

????
public?void?SetInterceptedComponentModel(ComponentModel?target)
????{
????????
//?獲取組件的aop配置
????????AspectDefinition?aspectDef?=?(AspectDefinition)?
????????????target.ExtendedProperties[
"aop.aspect"];

????????System.Diagnostics.Debug.Assert(?aspectDef?
!=?null?);

????????
//?InvocationDispatcher用于proxy的方法分派,ContainerInvocationDispatcher重寫了
????????
//ObtainInterceptorInstance方法,唯一的作用是:嘗試從IOC中獲取攔截器對象
????????_dispatcher?=?new?ContainerInvocationDispatcher(aspectDef,?_kernel);
????????_dispatcher.Init(_engine);
????}

????
public?object?Intercept(IMethodInvocation?invocation,?params?object[]?args)
????{
????????
//?a#內(nèi)幕:_dispatcher.Intercept會處理客戶的函數(shù)調(diào)用
????????
//Intercept方法會從ObtainInterceptorInstance獲取攔截器實(shí)例
????????
//(ContainerInvocationDispatcher中重寫的方法起作用了)
????????
//?如果沒有攔截器則直接Proceed,有攔截器則在攔截器進(jìn)行處理
????????
//這是a#攔截的一個(gè)簡單過程,詳細(xì)你可以參考:a#中的DefaultInvocationDispatcher源碼
????????return?_dispatcher.Intercept(?(IInvocation)?invocation,?args);
????}
}


而在ContainerInvocationDispatcher重寫的ObtainInterceptorInstance是這樣的:
///?<summary>
///?獲取攔截器對象
///?</summary>
protected?override?IMethodInterceptor?ObtainInterceptorInstance(Type?adviceType)
{
????
if?(_kernel.HasComponent(?adviceType?))
????{
????????
//?方式一:從IOC中獲取
????????
//如果我們把攔截器注冊進(jìn)IOC里面,這里就直接獲取
????????try
????????{
????????????
return?(IMethodInterceptor)?_kernel[adviceType];
????????}
????????
catch(InvalidCastException?ex)
????????{
????????????
//?In?this?case,?the?specified?interceptor
????????????
//?does?not?implement?the?IMethodInterceptor?from
????????????
//?AopAlliance

????????????String?message?
=?String.Format("The?interceptor?{0}?does?"?+?
????????????????
"not?implement?AopAlliance.Interceptor.IMethodInterceptor",?adviceType.FullName);?

????????????
throw?new?ApplicationException(message,?ex);
????????}
????}

????
//?方式二:從A#的DefaultInvocationDispatcher中獲取
????
//A#中對攔截器對象實(shí)例是有緩存處理的(一個(gè)HashTable:_type2AdviceInstance)
????return?base.ObtainInterceptorInstance(adviceType);
}


??????? 分析結(jié)束啦~ ,最后放上使用方法,很簡單的:

1)配置:
<configuration>
????
<facilities>
????????
<facility?id="aspectsharp">
<![CDATA[
import?AopDemo.Interceptors
import?AopDemo.Mixins

aspect?log?for?[AopDemo]
????pointcut?method(*)
????????advice(LoggerInterceptor)
????end
end

aspect?Security?for?[AopDemo]
????include?SecurityMixin
????pointcut?method(*)
????????advice(SecurityCheckInterceptor)
????end
end
]]>
????????
</facility>
????
</facilities>
</configuration>

2)初始化容器:
container?=?new?WindsorContainer(@"../../aspectsharp.ioc.xml");
container.AddFacility(
"aspectsharp",?new?AspectSharpFacility())?;
container.AddComponent(
"persondao",?typeof(PersonDao));

3)使用組件:
PersonDao?dao?=?container["persondao"]?as?PersonDao;
dao.Create(
"AAA");
...

完整demo下載地址:
http://www.wjshome.com/Income/Others/Castle.AspectSharp%20Facility.Demo.rar

bye~

轉(zhuǎn)載于:https://www.cnblogs.com/laiwen/archive/2005/09/07/231651.html

總結(jié)

以上是生活随笔為你收集整理的Castle实践9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。