7

必要な依存関係をコンストラクターに注入する MVP で依存関係注入を使用しようとしています。私が抱えている問題は、ルートの MainWindowPresenter で依存性注入を使用すると、すべてのサブプレゼンターとそのサブプレゼンター、ビュー、およびサービスが起動時に読み込まれることです。すべてが MainWindowPresenter から直接または間接的に読み込まれるため、起動時にアプリケーション全体がメモリに読み込まれることになります。

起動時にすべてのオブジェクトを作成するのに .NET で多くのコストがかからないことはわかっていますが、すべてが同時に使用されることはないため、メモリの無駄だと考えずにはいられません。AboutPresenter や HelpPresenter など、まったく使用されないものもあります。私は行方不明ですか、それとも依存性注入がどのように機能するはずですか? これを回避する方法はありますか?

これを回避する唯一の方法は、必要に応じてサブプレゼンター/ビュー/サービスを作成できるファクトリを使用することです。例えば:

class HelpFactory : AbstractHelpFactory
{
    public IHelpPresenter Create()
    {
         IHelpService helpService = new ConcreteHelpService();
         IHelpView helpView = new ConcreteHelpView();

         HelpSearchPresenter searchPresenter = HelpSearchFactory.Create();

         return HelpPresenter(helpView, helpService, searchPresenter);
    }
}

これは基本的にファクトリーがサブファクトリーに依存するのと同じことですが、少なくともそれらはプレゼンター/ビュー/サービスよりも軽量であり、必要になるまでサブファクトリーをロードする必要はありません。

4

1 に答える 1

2

考えられる解決策はいくつかあります (一般的なものから特定のものまで)。

構成ルート

構成ルートを決定します。これは、モジュールが一緒に構成されるアプリケーション内の (できれば) 一意の場所ですこれは、すべての依存関係を構成するための望ましいソリューションです。

抽象工場

依存関係を注入する代わりに、同様の依存関係のファクトリを注入できます。これは、依存関係の作成を延期し、現在の状況に必要な依存関係のみを解決するのに役立ちます。ninject.extension.factoryを使用した例:

kernel.Bind<IDependencyFactory>().ToFactory();

kernel
    .Bind<IDependency>()
    .To<DependencyImpl1>()
    .NamedLikeFactoryMethod((IDependencyFactory f) => f.GetJob());

var abstractFactory = kernel.Get<IDependencyFactory>();

var dependency = abstractFactory.GetJob(); 

public abstract class IDependency { }
public class DependencyImpl1 : IDependency { }
 
public interface IDependencyFactory
{
    IDependency GetJob();
    Lazy<IDependency> GetLazyJob();
}

これは、コンストラクターの過剰注入など、クラスの過剰注入を回避するのにも役立ちます

集約サービス

依存関係を注入する代わりに、処理ルーチンを集約するサービスを注入します。サービスを集約するためのリファクタリングで詳細を読む

遅延読み込み

起動時に作成するのに費用がかかりすぎる、またはほとんど使用されないなどの理由で、依存関係の解決を延期する必要がある場合があります。このような場合、IDependency の代わりに Lazy を注入できます。Ninject.Extension.Factory を使用した例:

kernel
    .Bind<Lazy<IDependency>>()
    .To<Lazy<IDependency>>()
    .NamedLikeFactoryMethod((IDependencyFactory f) => f.GetLazyJob());

var abstractFactory = kernel.Get<IDependencyFactory>();

var lazyDependencyUsingFactory = abstractFactory.GetLazyJob();

ファクトリなしの遅延読み込みを使用した例:

kernel
    .Bind<IDependency>()
    .To<DependencyImpl1>();
    
kernel
    .Bind(typeof (Lazy<>))
    .ToMethod(context =>
            ((ILazyLoader) Activator.CreateInstance(typeof (LazyLoader<>).MakeGenericType(context.GenericArguments),
                                                    new object[] { context.Kernel })).Loader);

var lazyDependency = kernel.Get<Lazy<IDependency>>();

lazyDependency.Dump();
lazyDependency.Value.Dump();

ps : 完全なサンプルはこちらから入手できます

于 2013-01-21T16:30:15.383 に答える