1

複数のアセンブリに分割されたアプリケーションに取り組んでいます。各アセンブリは外界へのインターフェイスを提供し、インスタンスは Ninject ベースのファクトリを介して生成されます。

まあ、Code があります。これは実行中のアセンブリからのものです。

public class IsolationTestModule : NinjectModule
{
    public override void Load()
    {
        ServiceFactory sf = new ServiceFactory();
        Bind<IService>().ToMethod(context=>sf.CreatService()).InSingletonScope();
    }
}

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        IKernel kernel = new StandardKernel(new IsolationTestModule());
        IService service = kernel.Get<IService>();
    }
}

ServiceFactoryも に依存してNinjectいますが、独自のKernelと独自のがありModuleます。

public interface IService
{
    void Idle();
}

public interface IDependantService
{
    void IdleGracefully();
}

public class ServiceImpl : IService
{
    [Inject]
    public IDependantService DependantService { get; set; }

    public void Idle() 
    {
        DependantService.IdleGracefully();
    }
}

public class DependantServiceImpl : IDependantService
{
    public void IdleGracefully() { }
}

public class ServiceFactory
{
    private IKernel _kernel = new StandardKernel(new SuppliesModule());

    public IService CreatService()
    {
        return _kernel.Get<IService>();
    }
}

public class SuppliesModule : NinjectModule
{
    public override void Load()
    {
        Bind<IService>().To<ServiceImpl>().InSingletonScope();
        Bind<IDependantService>().To<DependantServiceImpl>().InSingletonScope();
    }
}

実際に何が起こるか: -instanceServiceFactoryのビルドが完了するまでは問題ありません。ServiceImpl次のステップでは、アプリケーション は依存関係kernelを解決しようとしますが、もちろん、例外で失敗します (バインディングが利用できず、型は自己バインド可能ではありません)。私の理解では、ファクトリのカーネルがそれを行う必要があります...実際、Ninjectがすぐに作成されなかったインスタンスでも依存関係を解決することに熱心であることを知りませんでした。これは確かに私に新しい地平を開きます;-)ServiceImplIsolationTestModuleIDependantService

これを一時的に解決するために、ServiceImpl以下に示すように、コンストラクター ベースのインジェクションに変更します。

public class ServiceImpl : IService
{
    public IDependantService DependantService { get; set; }

    [Inject]
    public ServiceImpl(IDependantService dependantService)
    {
        DependantService = dependantService;
    }

    public void Idle() 
    {
        DependantService.IdleGracefully();
    }
}

それでも、インジェクション戦略の変更を強制しないソリューションを希望します。インジェクションチェーンを分離する方法を知っている人はいますか?

4

1 に答える 1

1

あなたの観察は正しいです。Ninject は、 によって作成されたオブジェクトのプロパティ インジェクションを行いますToMethod。また、コンストラクター注入を使用するソリューションは正しい方法です。とにかく、コンストラクター注入は、Ninject を使用するための推奨される方法です。プロパティ インジェクションは、オプションの依存関係にのみ使用する必要があります。

考慮すべきことは、カーネルを 1 つだけ使用することです。アプリケーションで複数のカーネル インスタンスを使用することは非常にまれです。

于 2012-07-12T06:51:04.623 に答える