我正在尝试创建包含 DL、BL 和 GUI 模块的多层应用程序。DL 包含实体,BL 包含 ViewModel 和服务,GUI 包含控制器。我的目标是让 BL 了解 DL,而 GUI 了解 BL 但不了解 DL。
所以我有这样的实体层次结构(在DL中):
namespace DL
{
public abstract class EntityBase
{
public int Id { get; set; }
}
public class Student : EntityBase
{
public string Name { get; set; }
}
}
和 ViewModel 层次结构(在 BL 模块中):
namespace BL
{
public abstract class ViewModelBase
{
public int Id { get; set; }
}
public class StudentViewModel : ViewModelBase
{
public string Name { get; set; }
}
}
和服务(也在 BL 中):
using DL;
namespace BL
{
public interface IServiceBase<out TViewModel>
where TViewModel : ViewModelBase
{
TViewModel GetViewModel(int id);
}
public abstract class ServiceBase<TEntity, TViewModel> : IServiceBase<TViewModel>
where TViewModel : ViewModelBase, new()
{
public virtual TViewModel GetViewModel(int id)
{
return new TViewModel() { Id = id };
}
}
public class StudentsService : ServiceBase<Student, StudentViewModel>
{
}
}
我想在 GUI 中使用它:
using BL;
namespace GUI
{
class StudentController : ControlerBase<StudentsService, StudentViewModel>
{
public StudentController(StudentsService service)
: base(service)
{
}
public void DoSomething()
{
var s = this.service.GetViewModel(123);
}
}
class ControlerBase<TService, TViewModel>
where TService : IServiceBase<TViewModel>
where TViewModel : ViewModelBase
{
protected readonly TService service;
public ControlerBase(TService service)
{
this.service = service;
}
public TViewModel GetViewModel(int id)
{
return this.service.GetViewModel(id);
}
}
}
对我来说看起来不错。控制器知道 IService 和 ViewModels 并且一切都应该工作,但是当我尝试编译时,我收到以下错误消息:
错误 1 类型“DL.Student”在未引用的程序集中定义。您必须添加对程序集“DL,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”的引用。
好的,我了解 StudentsService 派生自“实体感知”的通用 ServiceBase。但是为什么编译器会打扰呢?此外,当我不在 Controller 中调用 GetViewModel 方法时,一切都会正确编译。为什么?当我在 StudentsService 中写出这样完全荒谬的方法时:
public new virtual StudentViewModel GetViewModel(int id)
{
return base.GetViewModel(id);
}
一切都正确编译。为什么?
最后 - 我应该怎么做,不要在我的所有服务中编写这种奇怪的“新虚拟”方法?