(转)ASP.NET MVC最佳实践(3)

原文地址:http://space.itpub.net/740297/viewspace-588913

3.在Global.asax中使用引导程序(Bootstrapper)
如果您在global.asax的Application_Start方法中执行过多的任务(例如配置Ioc/DI、注册路由、模型绑定器、视图引擎、启动应用相关的后台服务,等等)。例如在最新的Oxite源代码中有如下代码段:
protected virtual void OnStart()  {  
    setupContiner();    
    setupSite();    
    registerRoutes();    
    registerActionFilters();    
    registerModelBinders();    
    registerViewEngines();    
    registerControllerFactory();    
    launchBackgroundServices();  
}

你不认为它执行了过多的任务了吗?有什么方式能对其进行扩展?如何再往其中添加新的路由、模型绑定、视图引擎而无需修改它?它没有违背Open-closed原则吗?
引导程序(Bootstrapper)正是用来解决这些问题。创建Bootstrapper的过程如下:
a.创建一个Task接口
public interface IBootstrapperTask  
{  
    void Execute();  
}
b.为每种类型的任务创建一个类,并实现前面定义的接口,如:
public class RegisterControllerFactory : IBootstrapperTask  {  
    private readonly IControllerFactory _controllerFactory;  
  
    public RegisterControllerFactory(IControllerFactory controllerFactory)      {  
        _controllerFactory = controllerFactory;  
    }  
  
    public void Execute()   {  
        ControllerBuilder.Current.SetControllerFactory(_controllerFactory);  
    }  
}

public class RegisterRoutes : IBootstrapperTask  {  
    private readonly RouteCollection _routes;  
  
    public RegisterRoutes() : this(RouteTable.Routes)   {  
    }  
  
    public RegisterRoutes(RouteCollection routes)  {  
        _routes = routes;  
    }  
  
    public void Execute()   {  
        _routes.Clear();  
  
        _routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
        _routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "" });  
    }  

c.创建一个静态的Bootstrapper类来执行这些任务:
public static class Bootstrapper  {  
    static Bootstrapper()   {  
        ConfigureContainer();  
    }  
  
    public static void Run()  {  
        var tasks = ServiceLocator.Current.GetAllInstances<IBootstrapperTask>();  
  
        foreach(var task in tasks)  {  
            task.Execute();  
        }  
    }  
  
    private static void ConfigureContainer()  {  
        IUnityContainer container = new UnityContainer();  
  
        UnityConfigurationSection configuration = (UnityConfigurationSection) ConfigurationManager.GetSection("unity");  
        configuration.Containers.Default.Configure(container);  
  
        ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));  
    }  

d.修改Global.asax
protected void Application_Start()  {  
    Bootstrapper.Run();  
}
e.修改web.config,将任务像这样串接在一起:
<unity>  
    <typeAliases>  
        <typeAlias alias="IControllerFactory" type="System.Web.Mvc.IControllerFactory, System.Web.Mvc"/>  
        <typeAlias alias="ControllerFactory" type="UnityCommonServiceLocatorMVC.CommonServiceLocatorControllerFactory, UnityCommonServiceLocatorMVC"/>  
        <typeAlias alias="IBootstrapperTask" type="UnityCommonServiceLocatorMVC.IBootstrapperTask, UnityCommonServiceLocatorMVC"/>  
        <typeAlias alias="RegisterRoutes" type="UnityCommonServiceLocatorMVC.RegisterRoutes, UnityCommonServiceLocatorMVC"/>  
        <typeAlias alias="RegisterControllerFactory" type="UnityCommonServiceLocatorMVC.RegisterControllerFactory, UnityCommonServiceLocatorMVC"/>  
    </typeAliases>  
    <containers>  
        <container>  
            <types>  
                <type name="registerRoutes" type="IBootstrapperTask" mapTo="RegisterRoutes"/>  
                <type type="IControllerFactory" mapTo="ControllerFactory"/>  
                <type name="registerControllerFactory" type="IBootstrapperTask" mapTo="RegisterControllerFactory">  
                    <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">  
                        <constructor>  
                            <param name="controllerFactory" parameterType="IControllerFactory">  
                                <dependency/>  
                            </param>  
                        </constructor>  
                    </typeConfig>  
                </type>  
            </types>  
        </container>  
    </containers>  
</unity>

因此,通过使用引导程序(Bootstrapper)可以使应用程序是可扩展的,我们可以创建新的任务并在应用程序启动方法中执行它而无需修改任何东西。

 

原文地址:https://www.cnblogs.com/fcsh820/p/1867092.html