欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Castle實(shí)踐9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility) - 葉子的家 - 博客園

        在“Castle實(shí)踐8”介紹了A#的使用方法,那么A#如何和Castle IOC容器結合起來(lái)使用呢?在Castle的官方falicicies庫中,提供了AspectSharp Facility來(lái)讓我們可以很簡(jiǎn)單在IOC中使用A#。我把使用方法放在最后,題目說(shuō)了是要全面剖析這個(gè)facility的原理,借助這次分析讓我們對Castle IOC中的Falicity編寫(xiě)有更深的了解。

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

        明白了需求,那么就開(kāi)始分析吧:

protected override void Init()
{
    
if (FacilityConfig == nullreturn;

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

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

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

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


第一步:
private void RegisterAspectEngine()
{
    
// 獲取當前facility的配置,相當于獲取了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作為擴張屬性
    model.ExtendedProperties.Add("builder", builder);
    
// engine激活的時(shí)候執行AspectEngineActivator
    model.CustomComponentActivator = typeof(AspectEngineActivator);

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


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


第三步:注冊ioc的proxy工廠(chǎng)
/// <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 == nullreturn;

    
// 得到所有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í)候會(huì )用到
            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函數中創(chuàng )建的mixin對象
    object[] mixins = context.MixinsAsArray();

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


第四步:激活a# engine,導致AspectEngineActivator執行
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會(huì )回調
private void OnComponentRegistered(String key, IHandler handler)
{
    
// 檢查a#配置中是否包含組件的“切面”
    
//就是當前加入的這個(gè)組件是否需要aop(怎么說(shuō)呢??表達不太清晰,大家應該明白吧。請原諒~~)
    AspectDefinition[] aspects = 
        _engine.AspectMatcher.Match( handler.ComponentModel.Implementation, 
        _engine.Configuration.Aspects );

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

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

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

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

    
// TODO: Merge aspects

    
return aspects[0];
}

 


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


/// <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重寫(xiě)了
        
//ObtainInterceptorInstance方法,唯一的作用是:嘗試從IOC中獲取攔截器對象
        _dispatcher = new ContainerInvocationDispatcher(aspectDef, _kernel);
        _dispatcher.Init(_engine);
    }

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


而在ContainerInvocationDispatcher重寫(xiě)的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ǎn)單的:

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~

Feedback

# re: Castle實(shí)踐9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility)  回復   

2005-08-23 01:00 by 綠葉
補充:由于我下載的源碼里面 Union 函數是TODO,所以你在demo中可以發(fā)現,第二個(gè)point cut不起作用,原因就是這里。你可以把配置文件修改成這樣:

import AopDemo.Interceptors
import AopDemo.Mixins

aspect Security for PersonDao
include SecurityMixin
pointcut method(*)
advice(SecurityCheckInterceptor)
advice(LoggerInterceptor)
end
end

希望castle project那邊能夠更新得快點(diǎn)吧~也希望能更多人來(lái)關(guān)注castle。

# re: Castle實(shí)踐9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility)  回復   

2005-09-23 10:27 by alex
AOP Facility和 NHibernate Facility一起就會(huì )報錯!
我用的是最新castle-all.zip

# re: Castle實(shí)踐9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility)  回復   

2005-09-26 15:27 by Calvin
我想實(shí)現如下的功能,不知是否可行:利用AspectSharp Facility做到客戶(hù)端用統一的方法生成本地或remoting遠程對象。Spring.net是可以通過(guò)ForceInit做到這一點(diǎn)。Castle里面如何通過(guò)IOC來(lái)攔截對象的生成做到這一點(diǎn)呢?

# 要更加簡(jiǎn)單的請看。。。  回復   

2005-09-28 15:53 by xy
http://www.cnblogs.com/QPG2006/articles/245667.html
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Castle實(shí)踐
Castle IOC容器內幕故事(下)
Castle的IoC容器深入分析 - linkin park - 博客園
Castle 開(kāi)發(fā)系列文章
Castle 動(dòng)態(tài)代理介紹
spring中的AOP與IOC
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久