AndreFeijo
AndreFeijo

Reputation: 10629

C# Ninject: How to bind to method async

I am using Ninject 3.2.2.0 and I am trying to bind an async method.

This is what I got so far:

kernel.Bind<Task<MyInterface>>().ToMethod(async ctx =>
{
   var someData = await DoSomethingAsync();
   return new SomethingElse(someData);
}).InRequestScope();

My method DoSomethingAsync never gets called. I believe it's not being called because MyInterface is being requested, not Task<MyInterface>.

Any ideas?

Upvotes: 1

Views: 1462

Answers (2)

Steven
Steven

Reputation: 172666

The construction of your object graph should be reliable and fast. This excludes doing anything that is I/O related. This means that you should not do anything that is asynchronous at all.

Instead anything that is slow, unreliable or asynchronous should be postponed untill after the object graph is constructed.

Upvotes: 2

AndreFeijo
AndreFeijo

Reputation: 10629

I ended up making my binding sync

kernel.Bind<MyInterface>().ToMethod(ctx =>
{
   var someData = DoSomethingSync(); // <-- Made this one sync, see method below
   return new SomethingElse(someData);
}).InRequestScope();

Here is the 'magic'. I changed my method from:

private async Task<string> DoSomethingAsync() {
  var result = await DoSomethingElseAsync();
  return result;
}

To

private string DoSomethingSync() {
   string result = null;

   var runSync = Task.Factory.StartNew(async () => {
      result = await DoSomethingElseAsync();
   }).Unwrap();
   runSync.Wait();

   return result;
}

I know performance is affected because of the context switch, but at least it works as expected and you can be sure that it won't deadlock.

Upvotes: 0

Related Questions