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
来调用特殊查询。
因此,当我尝试将 PgCourseStore
与 ICourseStore
与不同的 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);
}
我有基本的通用接口
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
来调用特殊查询。
因此,当我尝试将 PgCourseStore
与 ICourseStore
与不同的 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);
}