1
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?

More than 3 years have passed since last update.

VB.NET + Windows Forms + Unity.Container で Dependency Injection(依存性注入)

Last updated at Posted at 2021-04-30

※ 個人blogに投稿した記事(投稿日:2019/12/11)をQiitaに移行しました

前置き

この記事はQiita Visual Basic Advent Calendar 2019 の11日目の記事です。

.NET Core 3.0 では WinForms が対応され、Visual Basic 16.0 (Visual Studio 2019) もリリースされました。
Visual Studio 2019 16.4 では、まだ .NET Core 3.1 + WinForms + Visual Basic のテンプレートは対応されていないようでしたが、
.NET Core 3系におけるVBの対応は前向きに進んでいるように見えるので、今後の展開に注目しています。

で(唐突)、Advent Calendar 用のネタが何か無いか探したところ、
Adaptive Code」で読んだ Unitiy を利用した Dependency Injection を VB + WinForms で行えるか試してみることにしました。

はじめに

まず、以下のコードはForm1の中でrepositoryのインスタンスをNewしているので、
Form1はrepositoryに依存している関係にあります。

Public Class Form1

    Private ReadOnly repository As New Repository

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show(Join(repository.getAll.ToArray, ","))
    End Sub

End Class

Unitiy.Container を用いた依存性注入

ここから依存性注入の形に変えていくには、RepositoryIRepositoryインターフェースで抽象化し、
コンストラクタの引数でインスタンスを渡す形に変更します。

Public Class Form1

    Private ReadOnly repository As IRepository

    Sub New(repository As IRepository)

        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        Me.repository = repository
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show(Join(repository.getAll.ToArray, ","))
    End Sub
End Class
Public Interface IRepository

    Function getAll() As List(Of String)

End Interface
Public Class Repository
    Implements IRepository

    Public Function getAll() As List(Of String) Implements IRepository.getAll
        Return New List(Of String) From {"1", "2", "3"}
    End Function
End Class

NuGet でUnity.Containerをインストールします。

20191209233730.png

メインエントリポイントModule Programを手動で追加して、
そこにコンテナの初期化とインターフェイスとインスタンス生成の紐付けを記述します。
名前空間UnityのImportを忘れずに。

Imports Unity

Public Module Program

    <STAThread()>
    Sub Main()

        Dim container As IUnityContainer = New UnityContainer

        container.RegisterInstance(Of IRepository)(New Repository())

        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(container.Resolve(Of Form1))
    End Sub
End Module

ポイントはcontainer.Resolve(Of Form1)により、
Form1のコンストラクタSub New(repository As IRepository)の引数repository
NewされたRepositoryのインスタンスが渡されることです。
依存性をクラスの外側から注入できたことになります。

Unity.Configuration を使って、App.Config でインターフェイスとインスタンスを紐付け

ここからさらに、Unity.Configuration を使って、
App.Config でインターフェイスとインスタンスの紐付けを記述する形に変更します。
NuGetからUnity.Configurationをインストールします。

20191209235045.png

インストール後、Programモジュールで名前空間Microsoft.Practices.Unity.Configurationをインポートします。
設定ファイルの値をContainerに読み込む拡張メソッドLoadConfigurationMicrosoft.Practices.Unity.Configurationに存在するためです。

Imports Unity
Imports Microsoft.Practices.Unity.Configuration

Public Module Program

    <STAThread()>
    Sub Main()

        Dim container As IUnityContainer = New UnityContainer
        container.LoadConfiguration()

        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(container.Resolve(Of Form1))
    End Sub
End Module

App.Config には以下を追加します。

<configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration" />
</configSections>
<startup>
   <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
 <assembly name="WindowsAppVb" />
 <namespace name="WindowsAppVb" />
<container>
  <register type="IRepository" mapTo="Repository" />
</container>
</unity>

assembly nameも記述しないと実行時に
「The type name or alias ”xxxxx“ could not be resolved. Please check your configuration file and verify this type name.”」
が発生しました。

以上、「VB.NET + Windows Forms + Unity で Dependency Injection(依存性注入)」でした。

1
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
1
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?