zoukankan      html  css  js  c++  java
  • Castle IOC容器实践之FactorySupport Facility

    摘要:FactorySupport Facility允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略:

    1.使用访问器来访问组件的实例

    2.使用静态方法或者实例方式来访问组件的实例

     

    主要内容

    1.概述

    2.为什么需要FactorySupport Facility

    3.如何使用

    4.常见的配置示例

    5.实现原理浅析

     

    一.概述

    FactorySupport Facility允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略:

    1.通过访问器来访问组件的实例

    2.通过静态方法或者实例方式来访问组件的实例

    二.为什么需要FactorySupport Facility

    为了回答这个问题,我们先来看一个简单的使用工厂的例子,如下代码所示:

    public interface IComponent 

    {
        
    void Display();
    }


    public class MyComponent : IComponent

    {
        
    public MyComponent()

        
    {   

        }


        
    public void Display()

        
    {
            Console.WriteLine(
    "MyComponent");
        }

    }


    public class MyFactory

    {
        
    public MyFactory()

        
    {

        }


        
    public IComponent Create()

        
    {
            
    return new MyComponent();
        }

    }

    现在要在程序中使用MyComponent的实例,简单一点会这样去写:

    public class App

    {
        
    static void Main()

        
    {
            MyFactory factory 
    = new MyFactory();

            IComponent comp 
    = factory.Create();

            comp.Display();

        }

    }

    正如你所看到的,在程序中使用new关键字创建了一个工厂的实例,再由工厂得到组件的实例。现在我们看使用FactorySupport Facility后带来了什么好处。工厂和组件的代码不变,仍然是:

    public interface IComponent 

    {
        
    void Display();
    }



    public class MyComponent : IComponent

    {
        
    public MyComponent()

        
    {

        }


        
    public void Display()

        
    {
            Console.WriteLine(
    "MyComponent");
        }

    }


    public class MyFactory

    {
        
    public MyFactory()

        
    {

        }


        
    public IComponent Create()

        
    {
            
    return new MyComponent();
        }

    }

    配置文件,现在你可以不用理解怎么去配置,后面会讲到。

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

        
    <facilities>

            
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />

        
    </facilities>

        
    <components>

            
    <component id="myfactory" type="FactorySupportDemo.MyFactory,FactorySupportDemo" />

            
    <component id="mycomp" type="FactorySupportDemo.MyComponent,FactorySupportDemo"

                factoryId
    ="myfactory" factoryCreate="Create"></component>

        
    </components>

    </configuration>

    使用组件的实例

    public class App

    {
        
    static void Main()

        
    {
            IWindsorContainer container 
    = new WindsorContainer("../../Basic.xml");


            IComponent instance 
    = (IComponent) container["mycomp"];

            instance.Display();

        }

    }

    看到了吗?我们并没有使用new关键字创建任何对象,只是把工厂、组件等通过配置文件抛给了IOC容器,再从容器中往外取的时候,就可以直接取到组件的实例,这些实例是由工厂自动创建的,这正是FactorySupport Facility的作用。

    三.如何使用

    知道了为什么需要FactorySupport Facility之后,下面就来看如何使用Facility。在前面的代码中大家都已经看到了,使用FactorySupport Facility是非常的简单。

    1.加入FactorySupport Facility到容器中,可以使用代码加入也可以使用配置文件。

    使用代码加入:

    IWindsorContainer container = new WindsorContainer("../../Basic.xml");


    container.AddFacility(
    "factorysupport",new Castle.Facilities.FactorySupport.FactorySupportFacility());

    使用配置文件:

    <facilities>

        
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />

    </facilities>

    2.加入组件时指定使用的是哪种方式

    如果使用访问器只需要指定访问器的名称就可以了:

    <component id="accessor.comp" 

        type
    ="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"

        instance-accessor
    ="Instance">

    </component>

    如果使用工厂方法,需要指定工厂ID和工厂方法:

    <component id="mycomp" 

                type
    ="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"

                factoryId
    ="mycompfactory" factoryCreate="Create">

    </component>

    四.常见的配置示例

    这是一些常见的配置示例,来自于Castle自带的测试代码中。

    1.访问器配置示例

    有这样一个单件类

    public class SingletonWithAccessor

    {
        
    private static readonly SingletonWithAccessor instance = new SingletonWithAccessor();

        
    private SingletonWithAccessor()

        
    {

        }


        
    public static SingletonWithAccessor Instance

        
    {
            
    get return instance; }
        }

    }

    配置文件如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

        
    <facilities>

            
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />

        
    </facilities>

        
    <components>

            
    <component id="accessor.comp" type="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"

                instance-accessor
    ="Instance"></component>

        
    </components>

    </configuration>

    2.普通工厂配置示例

    组件类和工厂类如下

    public class MyComp

    {
        
    public MyComp()

        
    {

        }

    }


    public class MyCompFactory

    {
        
    public MyComp Create()

        
    {
            
    return new MyComp();
        }

    }

    配置文件如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

        
    <facilities>

            
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />

        
    </facilities>

        
    <components>

            
    <component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory, Castle.Facilities.FactorySupport.Tests" />

            
    <component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"

                factoryId
    ="mycompfactory" factoryCreate="Create"></component>

        
    </components>

    </configuration>

    3.带参工厂配置示例

    组件类和工厂类如下:

    public class MyComp

    {
        
    private string storeName;

        
    private IDictionary props;

        
    internal MyComp()
        
    {

        }


        
    internal MyComp(String storeName, IDictionary props)

        
    {
            
    this.storeName = storeName;

            
    this.props = props;
        }


        
    public string StoreName

        
    {
            
    get return storeName; }
        }


        
    public IDictionary Props

        
    {
            
    get return props; }
        }

    }


    public class MyCompFactory2

    {
        
    public MyCompFactory2()

        
    {

        }


        
    public MyComp Create(String storeName, IDictionary props)

        
    {
            
    return new MyComp(storeName, props);
        }

    }

    配置文件如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

        
    <facilities>

            
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />

        
    </facilities>

        
    <components>

           
    <component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory2, Castle.Facilities.FactorySupport.Tests"></component>

            
    <component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"

                factoryId
    ="mycompfactory" factoryCreate="Create">

                
    <parameters>

                    
    <storeName>MyStore</storeName>

                    
    <props>

                        
    <dictionary>

                            
    <entry key="key1">item1</entry>

                            
    <entry key="key2">item2</entry>

                        
    </dictionary>

                    
    </props>

                
    </parameters>

            
    </component>

        
    </components>

    </configuration>

    4.使用自动装配工厂配置示例

    组件类和工厂类如下:

    public interface IMyService

    {

    }


    public class MyComp

    {
        
    private IMyService serv;

        
    internal MyComp()

        
    {

        }


        
    internal MyComp(IMyService serv)

        
    {
            
    this.serv = serv;
        }


        
    public IMyService Service

        
    {
            
    get return serv; }
        }

    }


    public class MyCompFactory3

    {
        
    public MyCompFactory3()

        
    {

        }


        
    public MyComp Create(IMyService serv)

        
    {
            
    return new MyComp(serv);
        }

    }

    配置文件如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

        
    <facilities>

            
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />

        
    </facilities>

        
    <components>

            
    <component id="myserv" service="Castle.Facilities.FactorySupport.Tests.Components.IMyService, Castle.Facilities.FactorySupport.Tests"

                type
    ="Castle.Facilities.FactorySupport.Tests.Components.DefaultMyService, Castle.Facilities.FactorySupport.Tests" />

           
    <component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory3, Castle.Facilities.FactorySupport.Tests"></component>

            
    <component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"

                factoryId
    ="mycompfactory" factoryCreate="Create">

                
    <!-- parameters is not necessary_u97 ?s it will auto wire --></component>

        
    </components>

    </configuration>

    五.实现原理浅析

    FactorySupport Facility的实现也是非常的简单,主要是通过两个ComponentActivator来实现,分别为AccessorActivatorFactoryActivator,根据配置文件的不同调用不同的Activator

    String instanceAccessor = model.Configuration.Attributes["instance-accessor"];

    String factoryId 
    = model.Configuration.Attributes["factoryId"];

    String factoryCreate 
    = model.Configuration.Attributes["factoryCreate"];


    if (instanceAccessor != null)

    {

        model.ExtendedProperties.Add( 
    "instance.accessor", instanceAccessor );

        model.CustomComponentActivator 
    = typeof(AccessorActivator);

    }


    else if (factoryId != null)

    {

        model.ExtendedProperties.Add( 
    "factoryId", factoryId );

        model.ExtendedProperties.Add( 
    "factoryCreate", factoryCreate );

        model.CustomComponentActivator 
    = typeof(FactoryActivator);

    }

    好了,关于FactorySupport Facility就介绍到这儿,更多Castle的文章您可以访问《Castle 开发系列文章》。

     

    PDF版本下载/Files/Terrylee/FactorySupportFacility.rar

    示例代码下载/Files/Terrylee/FactorySupportDemo.rar

     

    参考资料

    Castle的官方网站http://www.castleproject.org

    (出处:博客园http://terrylee.cnblogs.com

  • 相关阅读:
    linux环境变量
    linux make configure make
    摘自(http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html)
    linux eaccelerator
    linux du df ls
    linux phpize
    mysql 分页
    mysql 执行计划和慢日志记录
    mysql 添加/删除列(column)
    mysql 索引
  • 原文地址:https://www.cnblogs.com/Terrylee/p/castle_ioc_factorysupport_facility.html
Copyright © 2011-2022 走看看