1

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);
}

また、すべてが正しくコンパイルされます。なんで?

そして最後に、すべてのサービスでこの奇妙な「新しい仮想」メソッドを作成しないようにするにはどうすればよいですか?

4

0 に答える 0