【发布时间】:2023-04-03 03:38:01
【问题描述】:
我有基本的通用接口
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 方法时,一切正常。但是,当我尝试调用 Update、Delete 或 Create 方法时,我收到 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException 消息,表明 ICourseStore 没有 CreateAsync 方法的定义。
是的,我可以像 ICRUDStore 类型一样存储 store 并在需要时进行转换,但可能有更漂亮的解决方案吗?
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* 和 Find* 方法之间有任何有意义的区别。这两种方法都在我的基础 PgStore<Model> 类中定义(不在 PgCourseStore 中),而我只绑定 ICourseStore 和 PgCourseStore。
【问题讨论】:
-
我认为您的代码没有任何问题。假设
CourseController依赖ICourseStore通过构造函数设置store和PgCourseStore,CoursesController都注册到IoC容器。 -
同一个项目中有不同或冲突的程序集版本?
-
@BobDust 是的,PgCourseStore 与 ICourseStore 绑定并且所有控制器都已注册。更重要的是,正如我所说的 Find* 方法工作正常,我不知道为什么。 '将在 10 分钟内添加一些更新以使情况更加清晰。
-
@TravisIllig 没有得到你的问题,抱歉。就像引用两个具有相同方法/类/等的 dll 一样。在同一个命名空间中?如果是这样,那么没有。除了默认的 WebApi 之外,我根本没有引用任何内容。加上 autofac 或 dryioc(不能同时使用)。
-
@TonyYoung,你是如何编译上面更新的
BaseController的?其构造函数中的参数类型必须是Store。
标签: c# asp.net-web-api dependency-injection inversion-of-control autofac