1

ninjectで遊び始めたばかりですが、この問題を乗り越えることはできません。この設定を検討してください。

private static void RegisterServices(IKernel kernel)
{
   kernel.Bind<IDataTransaction>().To<DataTransaction>().InRequestScope();

   kernel.Bind<IdbAnalytics>().To<dbAnalytics>().InRequestScope();
   kernel.Bind<IdbMembership>().To<dbMembership>().InRequestScope();

   kernel.Bind<IAnalyticsWork>().To<AnalyticsWork>().InRequestScope();
   kernel.Bind<IMembershipWork>().To<MembershipWork>().InRequestScope();

   kernel.Bind<ILog>().To<Log>().InRequestScope();
   ...
}

上記のクラスにログが注入されている場合:

public class AnalyticsWork : IAnalyticsWork, IDisposable
{
    private readonly IdbAnalytics _Context;
    private readonly ILog _Log;

    public AnalyticsWork(IdbAnalytics Context, ILog Log)
    {            
        _Context = Context;
        _Log = Log;
        _Log.Write(LogEntryType.DEBUG, "Object Created");
    }
    ...
}

この問題は、Logオブジェクトが他のオブジェクト(AnalyticsWork / MembershipWork)よりも先に破棄されることです。アイテムを処分する順序を設定する方法はありますか?または、この設定に欠陥がありますか?

4

1 に答える 1

2

私はNInjectを使用していませんが、ログコンクリートを共有またはWebリクエストごとに登録しているようです(InRequestScopeおそらく、NInjectを使用していないことをお詫びしますので、それが何をするのかわかりません)。

私が使用したすべてのロガー、NLog、Log4Net、MSのLogging Application Blockなどについては、ログへの書き込みを開始したスーパークラスを呼び出し元クラスとして取得するため、Transient登録が必要です。Scoped

順序を破棄する限り、別のクラスがまだ依存している場合、オブジェクトを異なる順序で破棄することはできないため、IoCコンテナーでそれを制御することはできないと思います。何年も前にIoCContainersを最初に使い始めたときと同じ問題に遭遇し、「ええ、すべてをスコープとして登録します!」と思いました。ふふ、それはうまくいきませんでした。

オブジェクトは別の方法で登録する必要があると思います。本当にスコープが必要なアイテムのみをスコープし、それ以外はすべてtransientsまたはsingletons。私は通常、次のパターンに従います。

すべてsingletonをコーディングし、コーディングしますthread-safe
スレッドセーフでない場合は、それを作成し、transientそのように登録します。

unit-of-workでパターンを使用しない場合はORM、通常、ORMコンテナーを登録してScoped、リクエストの存続期間中のオブジェクトの変更と、後者のSaveChanges()(Entity Framework 4やNHibernateのセッションなど)を追跡できるようにします。

于 2012-07-17T00:16:38.857 に答える