Ich habe Basis generische SchnittstelleChild-Schnittstelle generische Schnittstelle IoC bindnig in C#
public interface ICRUDStore<Model> where Model : class
{
Task<IEnumerable<Model>> FindAsync();
Task<Model> FindAsync(int id);
Task UpdateAsync(int id, Model updatedRecord);
Task DeleteAsync(int id);
Task CreateAsync(Model record);
}
und es ist Kind-Schnittstelle
public interface ICourseStore : ICRUDStore<Course>
{
Task<IEnumerable<Course>> FindByMenuIdAsync(int menuId);
}
wo Course
Basismodell Klasse. Ich implementiere dieses Repository mit PgCourseStore : PgStore<Course>, ICourseStore
, wobei PgStore<Course>
eine Basisklasse für die Arbeit mit Postgres ist.
Ich habe abstrakte Basis Controller-Klasse
public abstract class BaseController<Model, Store> : ApiController
where Model : class
where Store : ICRUDStore<Model>
protected readonly Store store;
mit grundlegenden CRUD Methoden und seine untergeordneten Controller mit speziellen Abfragen CoursesController : BaseController<Course, ICourseStore>
wo ich store
Variable muß ICourseStore
sein, spezielle Anfragen zu nennen.
Also, wenn ich versuche, PgCourseStore
mit ICourseStore
mit verschiedenen IoC-Containern zu binden (wie DryIOC, Autofac) alles funktioniert gut, wenn FindAsync Methoden aus meiner Basissteuerung aufgerufen werden. Aber wenn ich versuche, Update-, Delete- oder Create-Methoden aufzurufen, bekomme ich Microsoft.CSharp.RuntimeBinder.RuntimeBinderException mit der Nachricht, dass ICourseStore keine Definition für die CreateAsync-Methode hat. Ja, ich kann store
wie ICRUDStore Typ speichern und es wenn ich brauche, aber kann es sein, gibt es schönere Lösung?
UPD:BaseController
sieht aus wie
public abstract class BaseController<Model, Store> : ApiController
where Model : class
where Store : ICRUDStore<Model>
{
protected abstract Model Parse(dynamic model);
protected readonly Store store;
public BaseController(ICRUDStore<Model> store)
{
this.store = store;
}
public virtual async Task<HttpResponseMessage> Get()
{
var records = await store.FindAsync();
return Request.CreateResponse(HttpStatusCode.OK, records);
}
public virtual async Task<HttpResponseMessage> Post(dynamic value)
{
var model = Parse(value);
await store.CreateAsync(model);
return Request.CreateResponse(HttpStatusCode.Created);
}
}
Und CourseController
public class CoursesController : BaseController<Course, ICourseStore>
{
public CoursesController(ICourseStore store) : base(store) { }
}
So kann ich keine meaningfull Unterschied * Create zwischen der Verwendung und finden * Methoden. Beide Methoden sind in meiner Basisklasse PgStore<Model>
(nicht in PgCourseStore) definiert, während ich nur ICourseStore und PgCourseStore binde.
Ich sehe nichts falsch mit Ihrem Code. Angenommen, 'CourseController' hängt über' ICourseStore' über einen Konstruktor ab, um 'store' und' PgCourseStore' zu setzen, 'CoursesController' sind alle im IoC-Container registriert. –
Verschiedene oder widersprüchliche Assembly-Versionen im selben Projekt? –
@BobDust Ja, PgCourseStore ist mit ICourseStore verbunden und alle Controller sind registriert. Noch mehr, wie ich schon sagte Find * Methoden funktioniert gut und ich kann nicht herausfinden, warum. Ich werde einige Updates hinzufügen, um die Situation in 10 Minuten klarer zu machen. –