У меня есть базовая общий интерфейсДетский интерфейс общего интерфейса IoC bindnig в 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);
}
, и это ребенок интерфейсу
public interface ICourseStore : ICRUDStore<Course>
{
Task<IEnumerable<Course>> FindByMenuIdAsync(int menuId);
}
где Course
является основным классом модели. Я реализую этот репозиторий с PgCourseStore : PgStore<Course>, ICourseStore
, где PgStore<Course>
является базовым классом для работы с Postgres.
У меня есть абстрактный базовый класс контроллера
public abstract class BaseController<Model, Store> : ApiController
where Model : class
where Store : ICRUDStore<Model>
protected readonly Store store;
с основными методами CRUD и его контроллер ребенка со специальными запросами CoursesController : BaseController<Course, ICourseStore>
, где мне нужно store
переменную быть ICourseStore
вызова специальных запросов.
Так что, когда я пытаюсь связать PgCourseStore
с ICourseStore
с различными контейнерами IoC (например, DryIOC, Autofac), все работает отлично, когда методы FindAsync вызывают из моего базового контроллера. Но когда я пытаюсь вызвать методы «Обновить», «Удалить» или «Создать», я получаю сообщение Microsoft.CSharp.RuntimeBinder.RuntimeBinderException с сообщением о том, что у объекта ICourseStore нет определения для метода CreateAsync. Да, я могу хранить store
, как тип ICRUDStore, и отбрасывать его, когда мне нужно, но может быть есть более красивое решение?
UPD:BaseController
выглядит
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);
}
}
И CourseController
public class CoursesController : BaseController<Course, ICourseStore>
{
public CoursesController(ICourseStore store) : base(store) { }
}
Так что я не вижу никакой разницы между Внушительные использованием Create * и * Найти методы. Оба эти метода определены в моем базовом классе PgStore<Model>
(а не в PgCourseStore), в то время как я привязываю только объекты ICourseStore и PgCourseStore.
Я не вижу ничего плохого в вашем коде. Предположим, что 'CourseController' зависит от' ICourseStore' через конструктор для установки 'store' и' PgCourseStore', 'CoursesController' все зарегистрированы в контейнере IoC. –
Различные или противоречивые версии сборки в одном проекте? –
@BobDust да, PgCourseStore привязан к ICourseStore и зарегистрирован всем контроллерам. Более того, как я сказал, методы Find * отлично работают, и я не могу понять, почему. Добавлю несколько обновлений, чтобы сделать ситуацию более ясной через 10 минут. –