6

私のプロジェクトは、サービスとリポジトリで構成されています (すべてのリポジトリが db コンテキストを共有しています)。サービス層の 1 つに、リポジトリを使用してデータベースに書き込む非同期メソッドがあります。このメソッドがコンテキストを使用できるようになる前に、Web リクエストは終了し、コンテキストを破棄します。この回答に記載されているように、 NamedScopesを理解しようとしました。私はまだそれを実装する方法を理解できないようです。私のプロジェクトがどのように構成されているかを示し、誰かがコード レベルで私を助けてくれることを願っています。

バインディング

    private static void RegisterServices(IKernel kernel)
    {
        //dbcontext
        kernel.Bind<EntityDatabaseContext>().ToMethod(context => new EntityDatabaseContext()).InRequestScope();

        //unit of work
        kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();

        //repositories
        kernel.Bind<IRepository<Account>>().To<Repository<Account>>().InRequestScope();

        //services
        kernel.Bind<IAuthenticationService>().To<AuthenticationService>().InRequestScope();
    }

AuthenticationService はコンストラクター注入を使用します

public AuthenticationService(UnitOfWork unitOfWork, IRepository<Account> accountRepository){}

AuthenticationService 内のメソッド

    //this is a background process
    public Task SomeMethodAsync(string text)
    {
        //spin it off into a new task
        return Task.Factory.StartNew(() => SomeMethod(text));
    }

SomeMethodを利用しaccountRepositoryます。さらに情報が必要な場合は教えてください。NamedScopesが解決策である場合、スレッドの問題を解決してください。私の場合、どのように実装すればよいですか?

基本的にバックグラウンド処理が実行されており、リクエストスコープによりninjectによって破棄されているコンテキストを使用しています。

4

1 に答える 1

6

バックグラウンドスレッドを実行すると、多くの問題が発生する可能性があることに注意してください。IISは、いつでもアプリプールをリサイクルすることを決定できます。これにより、スレッドがすぐに終了し(または、場合によってはまったく実行されなくなり)、アプリケーションが一貫性のない状態になります。

http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

非同期操作を実行する最も簡単でエラーが発生しにくい方法は、Windowsサービスを実装し、それらの非同期操作をWindowsサービスに委任することです(MSMQを使用するなど)。

それでも困難な道を進みたい場合は、これらの一貫性のない状況について読み、防止してくださいHostingEnvironment.RegisterObjectIRegisteredObject

Ninjectの部分は非常に簡単です。MyJobProcessorタスクを実行するために必要なすべての依存関係を取得するなど、ジョブプロセッサクラスを作成するだけです。を実装する必要がありますINotifyWhenDisposed。これを行う最も簡単な方法は、から派生することですDisposeNotifyingObject

public class MyJobProcessor : DisposeNotifyingObject, IRegisteredObject
{
    public void Execute() { ... }
    public void Stop(bool immediate) { ... }
}

このプロセッサーをコントローラーに注入し、タスクに開始させ、作業が終了したら破棄します。

Task.Factory.StartNew(() => 
    { 
        try 
        { 
            processor.Execute(); 
        } 
        finally 
        { 
            processor.Dispose); 
        }
    });

それが依存関係のスコープであることを指定します。

Bind<MyJobProcessor>().ToSelf().Named("MyJobProcessor").DefinesNamedScope("MyJobProcessorScope");
Bind<IUnitOfWork>().To<UnitOfWork>().WhenAnyAnchestorNamed("MyJobProcessor").InNamedScope("MyJobProcessorScope");
于 2012-08-02T07:05:22.400 に答える