私は現在、古いDataSet、ストアドプロシージャWinFormアプリケーションをEntity Frameworkを使用するように変換して、新しいWebサイトが同じオブジェクトモデルとリポジトリにアクセスできるようにするプロジェクトに取り組んでいます。
とにかく、ユニットテストにモックリポジトリを使用できるように、フォームに依存性注入を実装しようとしています。以前MVCWebサイトで使用したという単純な理由で、Ninjectを使用していますが、WinFormアプリケーションでこれを実装しようとすると、控えめに言っても問題が発生し、WinFormsのDIに関する情報が不足しているためにさらに妨げられます。ウェブ。
これまでにNinjectFactoryとリポジトリを作成しましたが、リポジトリをフォームに注入することはあまりできませんでした。
したがって、誰かが私を助けたり、何か提案をしたりできますか?
以下に、役立つ可能性のあるコードの一部を示します。
Ninject Factory:
public class NinjectFactory : NinjectModule
{
private IKernel _ninjectKernel;
public NinjectFactory()
{
_ninjectKernel = new StandardKernel();
}
public override void Load()
{
_ninjectKernel.Bind(typeof(IRepository<>)).To(typeof(GenericRepository<>));
_ninjectKernel.Bind(typeof(IProductionRepository)).To(typeof(ProductionRepository));
}
}
リポジトリ付きのフォーム:
Public Class TaskForm
Inherits BaseBusinessDialogForm
Private _repository As TaskRepository
Private _task As Production.Task = Nothing
Public Sub New(ByVal task As Production.Task)
InitializeComponent()
_repository = New TaskRepository(ConnectString)
If task.TaskID = 0 Then
_task = task
Else
_task = _repository.GetByID(task.TaskID)
End If
MyBase.BusinessObject = _task
Me.TaskBindingSource.DataSource = MyBase.BusinessObject
End Sub
上記のフォームを保持するMDIフォームを起動するクラス:
Dim kernel As IKernel = New StandardKernel(New NinjectFactory())
''Dim kernel As IKernel = New StandardKernel(New NinjectFactoryTest())
mfrmMDI = kernel.Get(Of Forms.MDI)()
Application.DoEvents()
mfrmMDI.ShowDialog()
私の質問は少し曖昧であることは理解していますが、問題がどこにあるのか、何を完了する必要があるのかわかりません。
どうもありがとう
解決策の1つのエントリポイントとしてコンポジションルートを作成します。 INjectModuleをパラメーターとして渡して、異なる方法でテストするように構成できるようにします。 Composition Rootの利点の1つは、すべてのアセンブリがNInjectに依存するわけではなく、解決ロジックを変更するための単一のポイントがあることです。将来、IoCコンテナを変更したり、動的インターセプトを導入したりする可能性がある場合、これは本当にクールなパターンです。
_public class CompositionRoot
{
private static IKernel _ninjectKernel;
public static void Wire(INinjectModule module)
{
_ninjectKernel = new StandardKernel(module);
}
public static T Resolve<T>()
{
return _ninjectKernel.Get<T>();
}
}
_
モジュールは次のようになります
_public class ApplicationModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRepository<>)).To(typeof(GenericRepository<>));
}
}
_
Mainメソッドでは、ApplicationModule
をパラメーターとして渡し、_Form1
_を解決して開始します。
_[STAThread]
static void Main()
{
CompositionRoot.Wire(new ApplicationModule());
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(CompositionRoot.Resolve<Form1>());
}
_
_Form1
_コンストラクターでは、特定の閉じたジェネリックパラメーターを使用して必要なリポジトリを渡します
_public partial class Form1 : Form
{
private IRepository<Process> _processRepository;
public Form1(IRepository<Process> productionRepository)
{
this._processRepository = productionRepository;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(_processRepository.ToString());
}
}
_
リポジトリは非常に複雑になる可能性がありますが、依存関係が正しく解決されたかどうかを確認できるように、ToString()
メソッドの代わりに機能を追加しません。リポジトリには属性がまったくないことに注意してください。
_public interface IRepository<T>
{
}
public class GenericRepository<T> : IRepository<T>
{
public override string ToString()
{
return "MyRepository with type : "+typeof(T).Name;
}
}
_
これで、アプリケーションを実行すると、すべてが配線され、メッセージボックスにProcess
として囲まれたタイプが表示されることがわかります。