Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the lack of the async keyword in interfaces break DI in C#5.0?

Tags:

c#

I was excited to create my first app with C#5.0, and I wanted to use the async/await keywords to ease the pains of async data calls.

I'm a bit baffled that interfaces does not allow the async keyword to be part of the contract, as the await keyword only works for async marked methods. This would mean that it is impossible to call async methods through interface references. This also goes for abstract methods. Am I missing something here? This would mean that my regular DI-stuff will no longer work:

IAsyncRepository<T> {
 Task<IList<T>> GetAsync(); // no 'async' allowed
}

abstract class AsyncRepositoryBase<T> {
 public abstract Task<IList<T>> GetAsync(); // no 'async' allowed

// client code:

IAsyncRepository<Model> repo = ioc.Resolve<IAsyncRepository<Model>>();
var items = await repo.GetAsync(); // DOOOOOH, will not compile!

This is my current solution:

public abstract class AsyncRepositoryBase<T>
{
    protected Task<IList<T>> _fetcherTask;

    protected AsyncRepositoryBase(Task<IList<T>> fetcherTask)
    {
        _fetcherTask = fetcherTask;
    }

    public virtual async Task<IList<T>> GetASync()
    {
        return await _fetcherTask;
    }
}

Will I have to choose between abstraction and the langauge feature? Please tell me I'm missing something.

like image 803
tuxbear Avatar asked Oct 22 '12 23:10

tuxbear


1 Answers

await keyword only works for async marked methods

There's your problem. While await has to be inside an async method, it can await on any task, whether implemented via async or not.

For example:

interface IFoo {
    Task BarAsync();
}

class Foo : IFoo {
    public async Task BarAsync() {
        // Implemented via async/await in this case.
        // You could also have implemented it without async/await.
    }
}

// ...

async void Test() {
    IFoo foo = ... ;
    await foo.BarAsync(); // Works no matter how BarAsync is implemented.
}

As for your syntax error: await repo.GetAsync(); // DOOOOOH, will not compile! - did you forget to mark the method containing this piece of code as async (you don't have to mark the IAsyncRepository.GetAsync as async)?

like image 71
Branko Dimitrijevic Avatar answered Oct 06 '22 00:10

Branko Dimitrijevic