寂しさがこんなに美しい:アプリケーションから離れるスタート、初期化コードをより美しくする

8093 ワード

ここでの「寂しさ」はASP.NETプログラムの初期化コードはGlobal.asax.csのApplication_Start()メソッドでは、個別のプログラムセットに移動し、このプログラムセットはWebプロジェクトのプログラムセットと何の付き合いもありません.例えば、初期化コードが存在するプログラムセットをCNBlogsと呼ぶ.BootStrapper、WebプロジェクトのプログラムセットはCNBlogsと呼ばれています.Web、Visual Studioでは、この2つのプロジェクトの間には参照関係がありません.
低結合で寂しくなったが、コードはもっと美しくなった.生活の中で、寂しさは人の心の静かさを保つことができて、もっと多くの思考の美しさを楽しむことができます.
この文章は2つの方法で初期化コードをより美しくします.
1)PreApplicationStartMethod(ASP.NET 4.0の新機能、詳細はここを参照).
2)Bootstrapper(codeplex上のオープンソースプロジェクト、詳細はhttp://bootstrapper.codeplex.com/を参照).
アプリケーションの使用スタート()のシーン
まずBootstrapperを使わないで、そのままApplication_Start()を初期化するサンプルコード:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

protected void Application_Start()
{
//MVC
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

//IOC
var container = IoCFactory.Instance.CurrentContainter;
container.RegisterType<IBlogSiteService, FakeBlogSiteService>();
container.RegisterType<IBlogPostService, FakeBlogPostService>();
}

これはよく使われるシーンで、Application_Start()では初期化登録と構成が完了していますが、これらのコードが積み重なっていて、いつも気に入らないように見えます.
テストドライバ開発(TDD)を使用すると、見た目が悪いだけでなく、使用してもうまくいかない.テスト項目でも初期化が必要であるため、テスト項目ではApplication_を呼び出すことができない.Start()メソッド.
この初期化コードの一部を独立したプログラムセット(CNBlogs.BootStrapper)に移動したのは、テストが必要だったからです.独立後、Application_スタート()とテスト項目はCNBlogsを呼び出す.BootStrapper.Initializer.Initialize()メソッドは初期化を完了します.
これで独立したが、寂しくもなく、美しくもない.理由:
  1. WebプロジェクトはCNBlogsに依存する.BootStrapper;
  2. これらの初期化コードは依然としていくつか積まれており、場所を変えただけです.
解決策
最初の質問に対して»ASP.NET 4.0の新しい特性PreApplicationStartMethodが解決します.CNBlogsでBootstrapperプロジェクトのAssemblyInfo.csは次のコードを追加します.
[assembly: PreApplicationStartMethod(typeof(CNBlogs.Bootstrapper.Initializer), "Initialize")]

注意:CNBlogs.Bootstrapper.Initializerは静的クラス,InitializeにおけるInitializerにおける静的メソッドである.
  ASP.NET Runtimeは自動的にプログラムセットでこの定義を発見し、Application_を呼び出します.Start()の前に、ここで指定したInitializeメソッドを実行します.
注意が必要なのはRegisterAllAreas();Application_にしか置けませんStart()で実行します.そうしないと、エラーが発生します.
  This method cannot be called during the application's pre-start initialization stage.
2番目の問題について»Bootstrapperを介して異なる初期化コードを異なるタスク(IStartupTaskインタフェースを実装)に編成し、Bootstrapを通過する.BootstrapperのFluent APIは、これらのタスクを呼び出し、タスクの実行順序を指定します.たとえば、2つのタスクIocRegisterTaskとRegisterRoutesTaskがあります.IocRegisterTaskは先に実行します.この2つのタスクを実行するコードは次のとおりです.
public static class Initializer
{
public static void Initialize()
{
Bootstrap.Bootstrapper.With.StartupTasks()
.UsingThisExecutionOrder(s => s.First<RegisterRoutesTask>().Then<IocRegisterTask>())
.Start();
}
}

IoCRegisterTaskの実装コードは以下の通りである.
public class IocRegisterTask : IStartupTask
{
#region IStartupTask Members

public void Run()
{
var container = IoCFactory.Instance.CurrentContainter;
container.RegisterType<IBlogSiteService, FakeBlogSiteService>();
container.RegisterType<IBlogPostService, FakeBlogPostService>();
}

public void Reset()
{
}

#endregion
}

RegisterRoutesTaskの実装コードは次のとおりです.
public class RegisterRoutesTask : IStartupTask
{
#region IStartupTask Members

public void Run()
{
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}

private void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

public void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

public void Reset()
{
}

#endregion
}

小結
コードの美しさは文学、絵画、音楽と同じように、最も美しくなく、もっと美しいだけだ.その中の過程は果てしなくて、その中の楽しみも果てしなくて、もちろん前提はあなたが本当にそれが好きです.プログラムを書くのは青春ご飯を食べると言われていますが、これは絶対に間違った考えです.文学者、画家、音楽家は青春ご飯を食べていないので、プログラマーも同じです!ここまで書いて、ふと思ったのですが、その年の古い頃、若い頃に書いたコードを出して再構築すると、きっと面白いと思います!