3

開発中の新しいアプリケーションに nInject を使用する方法を学んでおり、単純なコンソール アプリにコピー/貼り付けできる次のサンプル コードを作成しました。IFoo のインスタンスを正常に返しますが、それについて質問があります。

「新規」を実行せずに FooManager クラスが Foo オブジェクトのインスタンスを作成するようにコードを変更するにはどうすればよいでしょうか。カーネルも注入する必要がありますか? しかし、カーネルが挿入され、行を read に変更した場合、それはvar foo = _kernel.Get<IFoo>()サービス ロケーターのアンチパターンを導入していませんか?

namespace IOCTest
{
    class Program
    {
        static void Main(string[] args)
        {
            using (IKernel kernel = new StandardKernel(new StandardModule()))
            {
                // do something with the kernal
                var mgr = kernel.Get<IFooManager>();
                var foo = mgr.GetById(1);
            }
        }
    }

    public class StandardModule : Ninject.Modules.NinjectModule
    {
        public override void Load()
        {
            Bind<IDatabase>()
                .To<Database>()
                .InTransientScope();

            Bind<IFooManager>()
                .To<FooManager>()
                .InTransientScope();
        }
    }

    //******************************************************

    public interface IDatabase
    {
        object[] GetScalar(int id);
    }

    public class Database : IDatabase
    {
        public object[] GetScalar(int id)
        {
            return new object[] { "RowName" };
        }
    }

    //******************************************************

    public interface IFooManager
    {
        IFoo GetById(int id);
    }

    public class FooManager : IFooManager
    {
        private IDatabase _db;

        public FooManager(IDatabase db) { _db = db; }

        public IFoo GetById(int id)
        {
            var results = _db.GetScalar(id);
            var foo = new Foo();   // <-- HOW DO I ELIMINATE THIS DEPENDENCY?
            foo.Name = results[0].ToString();
            return foo;
        }
    }

    //******************************************************

    public interface IFoo
    {
        string Name { get; set; }
    }

    public class Foo : IFoo
    {
        public string Name { get; set; }
    }

    //******************************************************
}
4

2 に答える 2

2

その依存関係を解消するには、いくつかの方法があります。データベースの依存関係で行ったのと同じことを行い、コンストラクター注入を使用できます。プロパティ インジェクションを実行できます ( https://github.com/ninject/ninject/wiki/Injection-Patterns )。別の方法、そしておそらくあなたが探しているのは、サービスの場所です。そのためには、FooManager ctor を更新して IKernel を要求することができます。これは自動的に解決され、渡されたカーネルを使用して Foo を取得できます。

public class FooManager : IFooManager
{
    private IDatabase _db;
    private IKernel _kernel;

    public FooManager(IDatabase db, IKernel kernel) { _db = db; _kernel = kernel;}

    public IFoo GetById(int id)
    {
        var results = _db.GetScalar(id);
        // var foo = new Foo();   // <-- HOW DO I ELIMINATE THIS DEPENDENCY?
        var foo = kernel.Get<IFoo>(); // Like this perhaps
        foo.Name = results[0].ToString();
        return foo;
    }
}
于 2012-04-10T15:42:52.327 に答える