Sto tentando di utilizzare dynamic
per aggirare gli inconvenienti causati dalla progettazione o dalla mancanza di esso (il "disagio" può essere trovato qui, se interessato Simplify method retrieving data from generic repository).Comportamento incoerente quando si utilizza await con tipo dinamico
Per farla breve, devo restituire la raccolta delle istanze Entity
. Classe è piuttosto semplice:
[JsonObject]
public class Entity
{
[PrimaryKey]
[JsonProperty(PropertyName = "id")]
public virtual int Id { get; set; }
[JsonIgnore]
public string Content { get; set; }
}
Così Entity
Basta Id
e Content
. Le classi ereditarie potrebbero avere altre proprietà, ma sono interessato solo alla parte Content
(JSON complesso).
È possibile accedere a tutti i tipi di entità diverse tramite Repository<T>
generico. Devo conoscere lo Type
della classe concreta perché le mappe T
alle tabelle SQLite sottostanti tramite il provider di dati, create su ORM di SQLite-net.
Così, per esempio, se ho Schedule : Entity
, allora sarei usando Repository<Schedule>
per manipolare tabella denominata Schedule
. Questa parte funziona bene.
Il problema principale è che "comandi" provengono dal client JavaScript, quindi ricevo richieste in formato JSON. In questo JSON ho una proprietà chiamata CollectionName
che specifica la tabella desiderata (e il tipo concreto).
Quello che mi serve/voglio è un bel pezzo di codice & pulito che può recuperare le entità da qualsiasi tabella data. Così, il metodo seguito avrebbe dovuto risolvere tutti i miei problemi, ma scopre che non ha ...
public async Task<IEnumerable<Entity>> GetAllEntitiesFrom(CollectionArgs args)
{
// args.CollectionName is type of entity as string
// namespace + collection name is mapped as correct type
// e.g. MyNamespace.Schedule
Type entityType = Type.GetType(
string.Format("{0}{1}", EntityNamespacePrefix, args.CollectionName), true, true);
// get correct repository type using resolved entity type
// e.g. Repository<MyNamespace.Schedule>
Type repositoryType = typeof(Repository<>).MakeGenericType(entityType);
dynamic repository = Activator.CreateInstance(repositoryType);
// Below `GetAllAsync()` returns `Task<IEnumerable<T>>`.
// this blocking call works 100%
//var entities = repository.GetAllAsync().Result;
// this non-blocking call works when it feels like it
var entities = await repository.GetAllAsync();
return entities;
}
Quindi, se (sopra) Io uso il blocco .Result
tutto funziona liek un fascino. Invece, se uso await
, il codice potrebbe o potrebbe non funzionare. Sembra davvero dipendere dalle posizioni dei pianeti e/o dagli sbalzi d'umore di Flying Spaghetti Monster.
a caso, ma il più delle volte, data la linea sarà gettando
Impossibile eseguire il cast oggetto di tipo 'System.Runtime.CompilerServices.TaskAwaiter'1 [System.Collections.Generic.IEnumerable'1 [MyNamespace.Schedule]] ' per digitare' System.Runtime.CompilerServices.INotifyCompletion '.
Sto usando .NET 4.0 Extended Framework.
Non era ben risposto laggiù - ma ancora - Sembra che si può evitare dinamico se il tipo di repository deriva da un non generico che può restituire un differito (abstract) GetAllAsync che Repository implementa. Quindi, invece di un repository dinamico, avresti un punto concreto da cui chiamare. –
Clay
Probabilmente non dovresti essere in attesa di un'espressione dinamica qui in primo luogo. Cosa c'è di sbagliato con 'await (Task>) repository.GetAllAsync()'? È meglio perché usa meno dinamica. –
usr
Non c'è 'T', solo' Tipo' risolto in fase di esecuzione. Non so davvero come farei a creare l'equivalente di '(Task>)' da 'typeof (Schedule)'. E 'T' non può essere semplicemente' Entity' (lancia l'eccezione). –