[Castle]Asp.Net中获取Castle容器中的服务的另一方法

我们知道在我们使用Castle IOC的时候,若你的类库在容器中的时候,你只需要通过公开属性或构造时设置参数后,Castle容器就会自动的根据配置文件中的服务为您实例化相应的类。但他并不支持Asp.Net的后置代码类。那么在Asp.Net中应如何获取容器中的服务呢?
我们可以通过如下方式:
IWindsorContainer container = ContainerAccessorUtil.GetContainer();
UserManage um 
= (UserManage)container["usermanage"];
其中usermanage就是配置文件中的component的ID.
我曾通过这个方式写了一个页面基类,页面继承该类后,就可以通过公开属性的方式来得到服务。
private BindingFlags BINDING_FLAGS_SET
            
= BindingFlags.Public
            
| BindingFlags.SetProperty
            
| BindingFlags.Instance
            
| BindingFlags.SetField
            ;


        
protected override void OnInit(EventArgs e)
        
{
            
//判断退出
            if (IsCheckLogin== true && this.UserId == -1)
            
{
                Response.Redirect(
"~/index.aspx");
            }


            IWindsorContainer container 
= ObtainContainer();

            Type type 
= this.GetType();

            PropertyInfo[] properties 
= type.GetProperties(BINDING_FLAGS_SET);

            
foreach (PropertyInfo propertie in properties)
            
{
                
string pname = propertie.Name;

                
if (container.Kernel.HasComponent(pname))
                
{

                    propertie.SetValue(
this, container[pname], null);
                }

            }

            
base.OnInit(e);
        }




        
public IWindsorContainer ObtainContainer()
        
{

            IContainerAccessor containerAccessor 
=

                 HttpContext.Current.ApplicationInstance 
as IContainerAccessor;
            
if (containerAccessor == null)
            
{
                
throw new ApplicationException("你必须在HttpApplication中实现接口 IContainerAccessor 暴露容器的属性");
            }


            IWindsorContainer container 
= containerAccessor.Container;
            
if (container == null)
            
{
                
throw new ApplicationException("HttpApplication 得不到容器的实例");
            }

            
return container;

        }

你也可以看 自由、创新、研究、探索…… 的博客上也有相应的介绍:在asp.net页面上得到Castle容器的实例

这是我以前的做法,今天所要讲的是另一种使用方式,通过HttpHandler的方式将每个页面的HttpHandler增加到Castle容器中。(以下代码来自互联网)
public class PageHandler : IHttpHandler, IRequiresSessionState
    
{
        
private static readonly ILog log = LogManager.GetLogger(typeof(PageHandler));

        
IHttpHandler Members

        
private IHttpHandler RegisterAspxPage(IHttpHandler handler, HttpContext context)
        
{
            
if (handler is IRuixinPage)
            
{
                
string pageKey = Guid.NewGuid().ToString();
                IWindsorContainer container 
= ContainerAccessorUtil.GetContainer();
                container.Kernel.AddComponent(pageKey, handler.GetType());

                
if (container.Kernel.HasComponent(handler.GetType()))
                
{
                    IHttpHandler newHandler 
= (IHttpHandler)container[handler.GetType()];
                    handler 
= newHandler;
                }

            }

            
return handler;
        }


        
private void RemoveAspxPage(IHttpHandler handler, HttpContext context)
        
{
            
if (handler is IRuixinPage)
            
{
                IWindsorContainer container 
= (context.ApplicationInstance as IContainerAccessor).Container;
                container.Release(handler);
            }

        }

    }

这样在我们的后置代码类中就可以通过公开属性的方式来获取容器中的服务。



posted @ 2006-12-11 16:00 福娃 阅读(905) 评论(10)  编辑 收藏 网摘 所属分类: Castle

  回复  引用  查看    
#1楼  2006-12-11 18:07 | Daniel Phang      
顶!
  回复  引用  查看    
#2楼 [楼主] 2006-12-11 18:13 | 福娃      
我顶你个肺!
  回复  引用  查看    
#3楼  2006-12-11 18:20 | Daniel Phang      
是我顶你!
太好了,这正是我想要的,顶
  回复  引用    
#5楼  2007-04-13 16:20 | gshzheng/zguosir [未注册用户]
to Maplye:
拜读了你的文章,有点体会,也有点疑问,请指点一下

1.只有在container中的对象,才会自动的根据类型注入.

2.container外的对象可以通过container["key"]来引用服务对象。
或者我们编写PageBase,来用container中的类型来注入page中的public属性,
就像你文章的上一部分那样。我看到NPetShop2中的web usercontrol都是继承
自Castal.Mvc的WebUserControlView,这个对象是不是也做了同样的事情。

3.我现在想用winform来引用象NPetShop2中的container服务,是不是也写个类似
上面的FormBase的东东。

4.你文章的下一部分没看明白,类PageHandler,该如何使用?比你第一种方案
有什么好处?MSDN中说“该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。”
什么意思?

问的有点多了:)

  回复  引用  查看    
#6楼 [楼主] 2007-04-13 16:34 | 福娃      
to gshzheng/zguosir
前三条都和你说的一样,关于第四条,这里的PageHandler是一个HttpHandler,同时需要在web.config文件中配置:<httpHandlers>
<add verb="*" path="*.aspx" type="Test.Web.HttpHandlers.PageHandler, Test.Web" />
</httpHandlers>,这样的话所有的.aspx都通过上面写的PageHandler来处理,上面的PageHandler的作用就是动态的将当前访问的页面的类型注册到容器中,这样的话,在后置代码中通过setter或constructor方式设置的一些容器内的服务,就能够自动的获取到!就是这样的道理,上面的代码来自Cuyahoga这个开源的项目。

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: