对于工作,我们有特定类型的记录,但每个项目都有自己的实现。列等是不同的,但通常过程是相同的(记录分为批次,批次分配,批次完成,批次返回,批次发送等)。许多列也很常见,但有时会有名称更改(一个中的BatchId与另一个中的Id相比。[Column(“name”)]负责此问题)。
目前,这是我使用界面中给出的通用组件实现批量分配功能的方法:
public interface IAssignment
{
// properties
...
// methods
T GetAssignmentRecord<T>(int UserId, int BatchId) where T : IAssignment;
List<T> GetAssignmentRecords<T>(int UserId) where T : IAssignment;
}
现在我有两个批量分配的项目。由于这些是在EntityFramework中完成的,Namespace1中的Assignment和Namespace2中的Assignment是完全不同的东西,但是受某些公共组件(ID,分配的用户,签入等)的约束,这些组件驱动所有返回它们的方法。
我认为我的主要问题是如果我做错了,如果有更好的方法来实现这一点,我可以将数据传输到我的控制器中,让控制器看起来有点类似于项目,同时具有尽可能多的方法工作是自动处理的(主要是为了在我需要进行更新时发生“修复一个,修复所有”的情况)。
以下是我如何为namespace1执行实现的示例:
public class Assignment
{
...
public T GetAssignmentRecord<T>(int UserId, int BatchId) where T : IAssignment
{
var db = new Database1Context();
return (T) Convert.ChangeType(db.Assignment.Where(c => c.UserId == UserId && c.BatchId == BatchId && c.Assigned).First(), typeof(T));
}
}
在控制器中:
Assignment assignment = new Assignment();
var record = assignment.GetAssignmentRecord<Assignment>(userid, batchid);
// do stuff
控制器代码实际上是我假设它可以工作的方式。我已经通过作业课完成了,如果我以正确的方式做这件事,我现在感到很困惑。我觉得这可能是不正确的原因是我基本上说“接口正在寻找一个通用的,我使用实体框架从数据库中获取一个强类型对象,我将它转换为通用,当我我正在提出请求,我要求的是我最初转换为通用的同类强类型对象。“
有更好的方法吗?或者我应该采取完全不同的方向?
答案 0 :(得分:3)
如果我理解了你的目标是什么,我会这样做,例如这样......
interface IAssignment
{
}
interface IRepo<out T> where T : IAssignment
{
T GetAssignmentRecord(int UserId, int BatchId);
IEnumerable<T> GetAssignmentRecords(int UserId);
}
class AssignmentRecord : IAssignment
{
}
class AssignmentWeb : IAssignment
{
}
class RepoDb : IRepo<AssignmentRecord>
{
public AssignmentRecord GetAssignmentRecord(int UserId, int BatchId)
{
//using(var db = new MyDbContext())
//{
// return db.Assignment.Where(c => c.UserId == UserId && c.BatchId == BatchId && c.Assigned).First();
//}
return new AssignmentRecord();
}
public IEnumerable<AssignmentRecord> GetAssignmentRecords(int UserId)
{
//using(var db = new MyDbContext())
//{
// return db.Assignment.Where(c => c.UserId == UserId && c.BatchId == BatchId && c.Assigned);
//}
return new List<AssignmentRecord>
{
new AssignmentRecord(),
new AssignmentRecord(),
new AssignmentRecord(),
new AssignmentRecord(),
new AssignmentRecord(),
new AssignmentRecord(),
new AssignmentRecord(),
new AssignmentRecord(),
};
}
}
class RepoWeb : IRepo<AssignmentWeb>
{
public AssignmentWeb GetAssignmentRecord(int UserId, int BatchId)
{
// fetch it from some web service...
return new AssignmentWeb();
}
public IEnumerable<AssignmentWeb> GetAssignmentRecords(int UserId)
{
//using(var db = new MyDbContext())
//{
// return db.Assignment.Where(c => c.UserId == UserId && c.BatchId == BatchId && c.Assigned);
//}
return new List<AssignmentWeb>
{
new AssignmentWeb(),
new AssignmentWeb(),
new AssignmentWeb(),
};
}
}
class MYController
{
public IRepo<IAssignment> Repository { get; set; } // you can inject this e.g. DI
public IAssignment GetAssignment(int userid, int batchid)
{
return Repository.GetAssignmentRecord(userid, batchid);
}
public IEnumerable<IAssignment> GetAllAssignments(int userid)
{
return Repository.GetAssignmentRecords(userid);
}
}
class ProgramAssignment
{
static void Main(string[] args)
{
try
{
var controller = new MYController();
controller.Repository = new RepoDb();
IAssignment assignment = controller.GetAssignment(0, 0);
IEnumerable<IAssignment> all = controller.GetAllAssignments(0);
controller.Repository = new RepoWeb();
assignment = controller.GetAssignment(0, 0);
all = controller.GetAllAssignments(0);
}
catch
{
Console.WriteLine("");
}
}
}
至于为什么out
- 在我的其他帖子中还有更多......
How to make generic class that contains a Set of only its own type or subtypes as Children?
答案 1 :(得分:1)
假设2 Assignment具有不同的属性(可能是一些额外的属性),但是一些属性是相同的,并且它们来自不同的数据库,有很多方法可以做到这一点。但“最好的”(对我来说)就是依赖注入。
您在Assignment类中的活动(方法)应该移动到一个单独的“服务”类。这增加了Assignment的模块性,因为它只是一个POCO。
对于数据访问,创建一个单独的类(存储库)以检索/插入/更新/删除您的数据。示例如下:
public AssignmentRepository: IAssignmentRepository{
public Assignment GetAssignmentRecord(int userId, int batchId){
}
}
public BatchAssignmentRepository: IAssignmentRepository{
public Assignment GetAssignmentRecord(int userId, int batchId){
}
}
如果你问为什么有2个存储库而不是1个,它会使代码多余吗?是的,但你也必须考虑它会增加模块性。如果您在BatchAssignment中更改了某些内容(可能更改了列名,添加了其他列等),那么您不需要在Assignment中应用相同的内容,并且避免使用“if batchAssignment else”逻辑。
来电者的使用方式如下:
IAssignmentService service = new AssignmentService();
IAssignmentRepository repository = new AssignmentRepository();
Assignment a = repository.GetAssignmentRecord(userId, batchId);
service.DoSomething(a);
答案 2 :(得分:1)
考虑适配器层。该层应该将输入数据转换为通用结构/类,然后可以一致地处理,尽管是泛型。当然,它也会在“出站”方面重新转换为特定数据库所期望的那一方。这假设没有数据源具有未在其他数据中定义的数据,或者您可以为所述缺失数据定义有效的默认值。
我想你需要为不同的项目使用不同的适配器。也许这是dependency injection的工作。基本上在运行时,您将获取所需的特定代码(适配器类)。