c#中通用接口IoC bindnig的子接口

Child interface of generic interface 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);
}

它是子界面

public interface ICourseStore : ICRUDStore<Course>
{
    Task<IEnumerable<Course>> FindByMenuIdAsync(int menuId);
}

其中 Course 是基本模型 class。 我正在使用 PgCourseStore : PgStore<Course>, ICourseStore 实现此存储库,其中 PgStore<Course> 是使用 Postgres 的基础 class。

我有抽象基础控制器class

 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 来调用特殊查询。

因此,当我尝试将 PgCourseStoreICourseStore 与不同的 IoC 容器(如 DryIOC、Autofac)绑定时,当从我的基本控制器调用 FindAsync 方法时,一切正常。但是,当我尝试调用更新、删除或创建方法时,我收到 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException 消息,指出 ICourseStore 没有 CreateAsync 方法的定义。 是的,我可以像 ICRUDStore 类型一样存储 store 并在需要时进行转换,但可能有更漂亮的解决方案吗?

更新: 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* 和 Find* 方法有任何有意义的区别。这两种方法都在我的基础 PgStore<Model> class 中定义(不在 PgCourseStore 中),而我只绑定 ICourseStore 和 PgCourseStore。

dynamic 类型导致了运行时绑定错误。更改为 object 可以帮助您:

    public virtual async Task<HttpResponseMessage> Post(object value)
    {
        var model = Parse(value);
        await store.CreateAsync(model);
        return Request.CreateResponse(HttpStatusCode.Created);
    }