2017-02-16 39 views
1

Я использую Ninject 3.2.2.0, и я пытаюсь связать метод async.C# Ninject: Как привязываться к методу async

Это то, что я до сих пор:

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

Мой метод DoSomethingAsync никогда не вызывается. Я считаю, что его не вызывают, потому что запрашивается MyInterface, а не Task<MyInterface>.

Любые идеи?

ответ

3

Построение графика объекта должно быть reliable and fast. Это исключает возможность делать что-либо, связанное с I/O. Это означает, что вы должны не делать все, что является асинхронным вообще.

Вместо этого все, что является медленным, ненадежным или асинхронным, следует отложить до после построен граф объекта.

+0

Скажите, что есть метаданные объекта CurrentUser, которые должны быть запрошены из службы или базы данных или того и другого. И скажите, что у вас есть 5 объектов домена, которые зависят от CurrentUser. Собираетесь ли вы запросить эти данные 5 раз за запрос? Почему бы не связать Task с методом, который может его вернуть? Просто потому, что он возвращает задание, это не значит, что МОК его ждет. Объекты домена, которые требуют Task , могут ждать его. Разница в том, что данные запрашиваются только один раз. Зависимости все ждут одной и той же задачи. –

+0

@StewartAnderson: У меня такое ощущение, что вы задаете здесь новый вопрос. Если вы разместите его как таковое здесь на SO и предоставьте соответствующие данные (какой-то примерный код будет полезен) и разместите ссылку на этот вопрос здесь, в комментариях, я сделаю все возможное, чтобы ответить на этот вопрос. – Steven

+0

Сказать, что ваш МОК не должен иметь ничего общего с ним, помешало бы моему решению проблемы. Чтобы обобщить мое решение до одной строки кода привязки IOC: kernel.Bind <Задача >(). ToMethod (c => UserProvider.Get()). InRequestScope(); Все, что требует текущего пользователя, теперь получает асинхронно через IOC. Объекты, созданные IOC, которые требуют Task ждут задачи, но все эти объекты ждут одну и ту же задачу из-за .InRequestScope(). –

0

Я закончил тем, что делает мою обязательную синхронизацию

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

Вот 'волшебный'. Я изменил мой метод от:

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

Для

private string DoSomethingSync() { 
    string result = null; 

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

    return result; 
} 

Я знаю, что производительность зависит из-за переключения контекста, но, по крайней мере, это работает, как ожидалось, и вы можете быть уверены, что он не будет тупиковой ,