2

予選

  1. Ninject.MVC3 2.2.2.0 Nuget Package を使用して、Factory アプローチを使用してビジネス ロジック (BL) を分離する IDomain インターフェイスの実装をコントローラーに挿入しています。
  2. 以下を使用して、事前構成済みのNinjectMVC3.csに Ninject モジュールを登録しています。

    private static void RegisterServices(IKernel kernel)
    {
        var modules = new INinjectModule[]
        {
            new DomainBLModule(),
            new ADOModule()
        };
        kernel.Load(modules);
    }
    
  3. 私は悪魔的なService Locatorアンチパターンの致命的な呪いを避けようとしています。

ドメイン クラスは、次のシナリオで、IDBContext を介してインターフェイスの実装も注入しようとしている DBContext を使用します。

IDomainBLFactory :

public interface IDomainBLFactory
{
    DomainBL CreateNew();
}

DomainBLFactory :

public class DomainBLFactory : IDomainBLFactory
{
    public DomainBL CreateNew()
    {            
        return new DomainBL();
    }
}

コントローラーの名前空間で:

public class DomainBLModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDomainBLFactory>().To<DomainBLFactory>().InRequestScope();
    }
}

この時点で、Ninject コンストラクター インジェクションを使用して IDomainBLFactory 実装をコントローラーに問題なく挿入できます。

public class MyController : Controller
{
    private readonly IDomainBLFactory DomainBLFactory;
    // Default Injected Constructor
    public MyController(IDomainBLFactory DomainBLFactory)
    {
        this.DomainBLFactory = DomainBLFactory;
    }
    ... (use the Domain for performing tasks/commands with the Database Context)
}

今、私の中心的な問題。

DomainBL の実装では、IDBContextFactory を使用して、特定の DBContext (この場合は Entity Framework からの ADO DBContext) に依存関係を注入します。

IDbDataContextFactory

public interface IDbDataContextFactory
{
    myADOEntities CreateNew();
}

DbDataContextFactory

public class DbDataContextFactory : IDbDataContextFactory
{
    public myADOEntities CreateNew()        
    {
        return new myADOEntities ();
    }
}

ADOモジュール

public class ADOModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDbDataContextFactory>().To<DbDataContextFactory>().InRequestScope();
    }
}

DomainBL の実装で、DBContext オブジェクト ファクトリに必要なインターフェイスを挿入するという問題に直面しました。

public class DomainBL
{
  private readonly IDbDataContextFactory contextFactory;
  **** OPS, i tried to understand about 10+ Stackoverflow articles ***
  ...
}

私は何を試しましたか?

  1. コンストラクターを使用するには インジェクション。しかし、IDBContextFactory の Factory CreateNew() の呼び出しに何を挿入すればよいかわかりません。クリアの場合:

    public class DomainBLFactory: IDomainBLFactory        
    {
        // Here the constructor requires one argument for passing the factory impl.
        public DomainBL CreateNew()
        {
            return new DomainBL(?????)  // I need a IDBContextFactory impl to resolve.
            //It's not like in the MVC Controller where injection takes place internally
            //for the controller constructor. I'm outside a controller
        }
    }
    

    この便利な投稿で、私たちの唯一無二の真の友人であるRemo Gloorは、次のように引用して、私にとって可能な解決策をコメントで説明しています。このインターフェイスを実装し、そのコンストラクターに IResolutionRoot を追加し、このインスタンスを使用して必要なオブジェクトを取得します

    質問: Ninject.MVC3 と控えめなドメイン クラス アプローチを使用して、これを適切な方法で実装するにはどうすればよいですか? Service Locator アンチパターンでの中継で罰せられることなく IResolutionRoot を解決するにはどうすればよいですか?

  2. IDBContexFactory のプロパティ インジェクションを使用するには。矛盾するすべての観点とそれに関する理論的な説明を学び、読む過程で、DBContexFactory クラス コードのインジェクションを行う適切な方法ではないと推測できます。どうでも。とにかくうまくいきません。

    public class DomainBL
    {
    
      [Inject]
      public IDbDataContextFactory contextFactory
      {
          get;
          set;
      }
      //Doesn't works, contextFactory is null with or without parameterless constructor
      .... (methods that uses contextFactory.CreateNew()....
    
    }
    

    質問:何が欠けていますか? このアプローチが間違っていたとしても、プロパティは注入されていません。

  3. 呪われよ。DependencyResolver を使用して、スティグマと共に生きてください。これは機能し、適切な解決策が見つかるまでこのアプローチを続けます。この 10 日間、物事を正しく理解して実行しようとしても知識が不足していたので、これは本当にもどかしいものです。

    public class DomainBL
    {
      private readonly IDbDataContextFactory contextFactory;
      this.contextFactory = DependencyResolver.Current.GetService<IDbDataContextFactory>();
      //So sweet, it works.. but i'm a sinner.
    
    }
    

    質問:インターフェイス化された実装を注入するためのファクトリ アプローチと、ビジネス ロジックを分解するためのドメイン駆動型アプローチの使用についての私の理解に大きな間違いはありますか? 私が間違っている場合、どのパターンのスタックを自信を持って実装する必要がありますか?

    私は、この重要な問いを率直に明快に問うていない非常に大量の記事やブログを見てきました。


Remo Gloorは、www.planetgeek.ch/2011/12/31/ninject-extensions-factory- introduction で Ninject 3.0.0 RC 用の Ninject.Extensions.Factory を紹介しています。

質問:この拡張機能は、一般的なポーパス用の Ninject.MVC3 と組み合わせて機能しますか? そうすれば近い将来の希望になるはずです。

皆様のご指導に感謝いたします。多くの人がこのシナリオも役立つと思うと思います。

4

2 に答える 2

1

ServiceLocator アンチパターンに頼らずに問題を解決するための汎用 IFactory の実装を次に示します。

まず、素敵なジェネリック ファクトリ インターフェイスを定義します。

  public interface IFactory<T>
  {
    T CreateNew();
  }

そして、ninject カーネルを使用して要求されたオブジェクトを作成する実装を定義します。

  class NinjectFactory<T> : IFactory<T>
  {
    private IKernel Kernel;

    public NinjectFactory( IKernel Kernel )
    {
      this.Kernel = Kernel;
    }

    public T CreateNew()
    {
      return Kernel.Get<T>();
    }
  }

以下を使用してファクトリにバインドする

  private static void RegisterServices(IKernel kernel)
  {
    kernel.Bind<myADOEntities>().ToSelf();
    kernel.Bind<DomainBL>().ToSelf();
    kernel.Bind(typeof(IFactory<>)).To(typeof(NinjectFactory<>));
  }        

コントローラーで次のことができるようになりました。

  public class MyController : Controller
  {
    private readonly IFactory<DomainBL> DomainBLFactory;

    public MyController( IFactory<DomainBL> DomainBLFactory )
    {
      this.DomainBLFactory = DomainBLFactory;
    }

    // ... (use the Domain for performing tasks/commands with the Database Context)
  }

そしてあなたの DomainBL で

  public class DomainBL
  {
    IFactory<myADOEntities> EntitiesFactory;

    public DomainBL( IFactory<myADOEntities> EntitiesFactory )
    {
      this.EntitiesFactory = EntitiesFactory;
    }

    // ... (use the Entities factory whenever you need to create a Domain Context)
  }
于 2012-05-16T15:26:54.723 に答える
1

あなたの工場の目的がよくわかりません。通常、1 つの要求に対して正確に 1 つの ObjectContext インスタンスがあります。つまり、ファクトリは必要なく、単純myADOEntitiesに Request スコープにバインドしDomainBLて、ファクトリを追加せずにインジェクトでき​​ます。

Bind<myADOEntities>().ToSelf().InRequestScope();
Bind<DomainBL>().ToSelf().InRequestScope();

はい、ファクトリと mvc の拡張機能は連携して動作します。

于 2012-02-22T16:28:00.760 に答える