场景:我正在用Blazor重建几个网站,都是做电子商务的。我想做的是提取会计逻辑(即Orders
,OrderItems
,Accounts
,Transactions
等)和数据操作到一个"Accounting"DLL,这样我就不必重复代码了。
我已经在DLL中定义了上述Entities
,然后在WebApp.Server
的DbContext
中,我有适当的DbSets
。
在"会计"DLL中,我有一个接口:
public interface IDbAccountringService
{
DbSet<Account> Accounts { get; set; }
//etc
}
WebApp.Server
中DbContext实现的
public class Db : ApiAuthorizationDbContext<User>, IDbAccountringService
{
public Db(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
public DbSet<Account> Accounts { get; set; }
}
然后在"Accounting"DLL中,我有以下泛型类:
public class DbAccountingService<T> where T : DbContext, IDbAccountringService
{
DbContext dbContext { get; set; }
public DbAccountingService(DbContext T)
{
dbContext = T;
}
public Account[] GetAccounts()
{
//The compiler doesn't see Accounts
return dbContext.Accounts.ToArray();
//It also doesn't see Accounts on itself
return this.Accounts.ToArray();
// However, it does see all the DbContext methods
dbContext.SaveChanges();
}
}
,我实例化并在我的控制器中使用:
[Route("accounting/accounts")]
[ApiController]
public class JournalController : BaseApiController
{
DbAccountingService<Db> _dbAccountingService;
public JournalController(Db db, MtGlobals mtGlobals) : base(mtGlobals)
{
_dbAccountingService = new DbAccountingService<Db>(db);
}
[HttpGet("get-accounts")]
public Account[] GetAccounts()
{
return _dbAccountingService.GetAccounts();
}
}
如DbAccountingService<T>
中的注释所示,编译器承认dbContext
实际上是DbContext
,但它不承认它也实现了IDbAccountringService
。
我对泛型有点模糊,虽然我通常会让它们工作,但是,在这里,没有运气。
我想做的是可能的吗?我想把所有的数据操作提取到"会计"中。DLL,这样我就不必为每个网站编写重复的代码。
您的dbContext
字段类型为DbContext
:
DbContext dbContext { get; set; }
public DbAccountingService(DbContext T)
{
dbContext = T;
}
请注意,您的构造函数参数类型也是DbContext
,参数名称为T
。所以这个T与泛型类型参数无关,它只是一个参数名。
您希望dbContext
属性为泛型类型:
T dbContext { get; set; }
public DbAccountingService(T context)
{
dbContext = context;
}
相关的参数是,您的字段具有类型T(因为您的where约束它实现接口IAccountingService
)。