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 と ViewModel を認識しており、すべてが機能するはずですが、コンパイルしようとすると、次のエラー メッセージが表示されます。
エラー 1 タイプ 'DL.Student' は、参照されていないアセンブリで定義されています。アセンブリ 'DL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' への参照を追加する必要があります。
OK、StudentsService が「エンティティ対応」の汎用 ServiceBase から派生したことを理解しています。しかし、なぜコンパイラはそれを気にするのですか? さらに、コントローラーで GetViewModel メソッドを呼び出していない場合、すべてが正しくコンパイルされます。なんで?そして、StudentsService に次のような完全にばかげたメソッドを記述すると、次のようになります。
public new virtual StudentViewModel GetViewModel(int id)
{
return base.GetViewModel(id);
}
また、すべてが正しくコンパイルされます。なんで?
そして最後に、すべてのサービスでこの奇妙な「新しい仮想」メソッドを作成しないようにするにはどうすればよいですか?