0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【VB.NET MVC】Autofac導入でDI環境を構築(Web APIとの共存とOWIN連携)

Posted at

VB.NETでのWebアプリケーション開発で、「依存性の注入(DI)」を実現するためにAutofacを導入しようとして、MVCとWeb APIの両方で動かすのに苦労した経験を元に、調べて実践した内容をまとめました。

1. Autofacとは何か? なぜDIが必要なのか?

Autofacは、.NETで非常に人気のある「DIコンテナ」ライブラリの一つです。
DI(Dependency Injection / 依存性の注入)とは、クラスが必要とする別のクラス(依存オブジェクト)を、自分自身で生成するのではなく、外部から与えてもらう(注入してもらう)という設計原則です。

DIがない世界の問題点

Public Class MyController
    Private ReadOnly _myService As MyService

    Public Sub New()
        ' コントローラーが自分でサービスを生成している(密結合)
        _myService = New MyService()
    End Sub
End Class

上記の方法だと、MyServiceの仕様が変わるたびにMyControllerも修正が必要になり、テストもしにくくなります。

DIがある世界(Autofac利用)のメリット

Public Class MyController
    Private ReadOnly _myService As IMyService

    ' コンストラクタで外部から注入してもらう(疎結合)
    Public Sub New(ByVal service As IMyService)
        _myService = service
    End Sub
End Class

AutofacのようなDIコンテナが、IMyServiceというインターフェースに対して、どのクラス(例: MyService)のインスタンスを渡すかを管理してくれます。
これにより、クラス間の結びつきが緩やか(疎結合)になり、変更に強く、テストしやすいコードを書くことができます。

2. MVCとWeb APIでAutofacを共存させる

ASP.NET MVCプロジェクトでAPIも使いたい場合、ControllerとApiControllerの両方でDIを機能させる必要があります。そのために必要なのが、以下の2つのパッケージです。

  • Autofac.Mvc5: MVCコントローラー用
  • Autofac.WebApi2: Web APIコントローラー用

「WebApi5じゃなくてWebApi2でいいの?」と不安になりますが、これで正解です。
これはASP.NET Web APIのバージョンに基づいた命名規則であり、現在の環境でも問題なく動作します。

3. OWIN環境とは? なぜAutofac設定に必要なのか?

当初、私はGlobal.asaxのApplication_StartにAutofacの設定を書いていました。しかし、これだとWeb APIの設定でキャストエラーが発生します。この問題を解決する鍵がOWINでした。

OWIN (Open Web Interface for .NET) とは、一言でいうと.NETのWebサーバーとWebアプリケーションを分離するための「標準ルール」です。

OWIN環境では、リクエストからレスポンスまでの一連の処理を「パイプライン」として構築し、その処理一つ一つを「ミドルウェア」として追加していきます。

MVCとWeb APIは元々、独立した仕組みで動いていました。OWINパイプラインを使うことで、それらの処理が始まるより前の段階でAutofacのミドルウェアを組み込むことができます。これにより、両者でDIの管理方法が統一され、スムーズな連携が実現できるのです。

4. OWIN連携によるAutofacの設定手順

ここからは具体的な実装手順です。Global.asaxでの設定はやめ、OWINのStartupクラスにDI設定を集約します。

Step 1: 必要なNuGetパッケージをインストール

OWIN連携に必要なパッケージをすべてインストールします。Microsoft.Owin.Host.SystemWebは、IIS上でOWINを動かすための重要な「アダプター」です。

Install-Package Autofac.Mvc5.Owin
Install-Package Autofac.WebApi2.Owin
Install-Package Microsoft.Owin.Host.SystemWeb

Step 2: DIコンテナの構築処理を分離 (AutofacConfig.vb)

App_Startフォルダに、DIコンテナの登録ルールを記述するモジュールを作成します。

' App_Start/AutofacConfig.vb
Imports Autofac
Imports System.Web.Http
Imports System.Reflection
Imports Autofac.Integration.Mvc
Imports Autofac.Integration.WebApi

Public Module AutofacConfig
    Public Function Initialize(ByVal config As HttpConfiguration) As IContainer
        Dim builder = New ContainerBuilder()
        Dim executingAssembly = Assembly.GetExecutingAssembly()

        'MVCコントローラーを登録
        builder.RegisterControllers(executingAssembly)

        'Web APIコントローラーを登録
        builder.RegisterApiControllers(executingAssembly)

        'Web APIのフィルタープロバイダーを登録
        builder.RegisterWebApiFilterProvider(config)
        
        ' ... (DbContext、リポジトリ、サービスの登録) ...
        builder.RegisterType(Of ApplicationDbContext)().InstancePerRequest()
        builder.RegisterType(Of MyRepository)().As(Of IMyRepository)().InstancePerRequest()
        builder.RegisterType(Of MyService)().As(Of IMyService)().InstancePerRequest()
        ' ...

        'コンテナをビルドして返す
        Return builder.Build()
    End Function
End Module

Step 3: OWINパイプラインを構築 (Startup.vb)

App_StartフォルダにStartup.vbを作成し、アプリケーション起動時の処理を記述します。

' App_Start/Startup.vb
Imports Microsoft.Owin
Imports Microsoft.Owin
Imports Owin
Imports System.Web.Mvc
Imports System.Web.Http
Imports Autofac
Imports Autofac.Integration.Mvc
Imports Autofac.Integration.WebApi

' このアセンブリ属性は必須です。OWINがこのクラスを起動時に呼び出すための目印になります。
<Assembly: OwinStartup(GetType(YourNamespace.Startup))>
Namespace YourNamespace ' ← ご自身のプロジェクトの名前空間に必ず変更してください

    Public Class Startup
        Public Sub Configuration(ByVal app As IAppBuilder)
            ' 1. Web API用のHttpConfigurationを新規作成
            Dim config = New HttpConfiguration()

            ' 2. AutofacConfigを呼び出してDIコンテナを構築・取得
            Dim container = AutofacConfig.Initialize(config)

            ' 3. OWINパイプラインにAutofacのコア機能を登録(最重要)
            '    リクエストごとにDIの生存期間(スコープ)が作られるようになります。
            app.UseAutofacMiddleware(container)

            ' 4. MVC用の設定
            '    MVCの依存関係解決をAutofacに委譲します。
            DependencyResolver.SetResolver(New AutofacDependencyResolver(container))
            '    MVCの処理をOWINパイプラインに統合します。
            app.UseAutofacMvc()

            ' 5. Web API用の設定
            '    Web APIの依存関係解決をAutofacに委譲します。
            config.DependencyResolver = New AutofacWebApiDependencyResolver(container)
            '    Web APIのルート設定などを読み込みます。
            WebApiConfig.Register(config)
            '    Web APIの処理をOWINパイプラインに統合します。
            app.UseAutofacWebApi(config)
            app.UseWebApi(config)
        End Sub
    End Class
End Namespace

5. ハマりどころとエラー解消法

エラー1:「引数なしコンストラクターは定義されていません」

このエラーが出たら、OWINの起動プロセスが失敗していることを疑ってください。

  • 解決策① パッケージの確認 : Microsoft.Owin.Host.SystemWeb パッケージはインストールされていますか? これがないとStartup.vbが呼び出されません。
  • 解決策② 属性の確認 : Startup.vb の先頭にある 属性の名前空間は正しいですか? クラスの名前空間と完全に一致している必要があります。
  • 解決策③ デバッグ実行 : Startup.Configuration メソッドにブレークポイントを置き、起動時に処理が止まるか確認しましょう。もし止まらなければ、原因は①か②です。

エラー2:カスタムエラーページに飛ばされて真の原因がわからない

DIの設定ミスで実行時エラーが発生しているのに、カスタムエラーページが表示されて詳細がわからないケースです。

  • 解決策 : Web.config の タグの mode を一時的に "Off" に変更します。これで開発者向けの詳しいエラー画面(通称:Yellow Screen of Death)が表示され、「どのサービスの登録が漏れているか」といった根本原因を特定できます。エラーが解決したら、modeは忘れずに元に戻しましょう。

まとめ

VB.NET MVCとWeb APIが共存するプロジェクトでAutofacを導入する際は、OWIN連携が成功の鍵となることが分かりました。上記の方法で構築すれば、クリーンで保守性の高いコードを書くことができるようになります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?