2012-07-29 14 views
5

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

バインディング

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)); 
    } 
コンストラクタ・インジェクションを使用しています

SomeMethodaccountRepositoryを使用します。もう情報が必要な場合は教えてください。 NamedScopesが解決策である場合、スレッドの問題で私を助けてください、私はどのように私のケースでそれを実装するのですか?

基本的に、バックグラウンドプロセスが実行されており、要求スコープのためにninjectによって処分されているコンテキストを使用しています。

+1

達成したいことを具体的に教えてください。メソッドSomeMethodAsyncを非同期でロードするか、またはファッションのようなジョブ内の情報をバックグラウンド処理したいですか? デザインの大きな問題点の1つは、SomeMethodAsyncで直接新しいタスクを開始することです。新しいタスクを開始すると、タスクの実行についての約束はありません。リクエストが終了してからninjectがリクエストスコープ内にすでに配置された後にタスクが実行される可能性があります。 AsyncControllerを使用する場合は、タスクをその上に登録する必要があります。しかし、APIはそれを開始してはならない –

+0

@DanielMarbachそれは私の問題です、タスクは要求が終了した後に実行され、ninjectはコンテキストを破棄します。私は待つように命じる必要があります。これを行う方法がわかりません。 –

+0

@DanielMarbach APIがそれを開始してはならないとはどういう意味ですか? –

答えて

6

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

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

asyncronousの操作を実行し、最も簡単で最もエラーを起こしやすいwaytoは、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"); 
+0

ありがとう、Windowsサービスの使用に関しては、それはロギング(ユーザーがログインする、ログに記録する)、または送信するなどの状況に適していますか?いいえ、この質問の最初のインスタンスとこの1つのvtc'd - @Remo Gloor?メール(テンプレート)?これらの振る舞いによって、返されるまでに時間がかかります。そのため、私はバックグラウンドでそれらを好きです。 –

+0

@Lolcoderあなたはこのデータを失う余裕があるかどうかです。例えば。サーバが何らかのエラーによりリサイクルした場合、ログを持たないのではないでしょうか?または、あなたはEMailが送信されない状況で暮らすことができますか?ロギングと電子メールの送信には通常、依存関係は必要ありません。また、実際にどれだけのパフォーマンスが得られているかを確認する必要があります。タスクの作成と開始には時間がかかります。 –

+0

これらのいずれかが要求で同期して実行され、プールがリサイクルされても失敗しないでしょうか? – solipsicle

関連する問題