1

独自のライブラリであるデータ アクセス レイヤーには、ドメイン オブジェクトのデータベース テーブルを表す POCO クラスがあります。例として 1 つを使用できますが、それを と呼びましょうMyClassDTO。これと同じようなオブジェクトが数十あります。

独自のライブラリにもある(そしてDALライブラリを参照する)私のビジネスロジックレイヤーには、各オブジェクトの実際のドメインオブジェクトクラスがあります。を使いましょうMyClass

BLL は API としてMyClassBll、ドメイン ロジックとデータにアクセスするためにプレゼンテーション プロジェクト内でインスタンス化できる のような一連のクラスを公開します。

私の人生を楽にするために、ほとんどの BLL オブジェクトMyClassBllはジェネリック抽象Bll<TModel,TDto>クラスから継承します。したがって、たとえばMyClassBll次のように宣言されます。

Public Class MyClassBll : Bll<MyClass,MyClassDto>

ここでのアイデアは、プレゼンテーション層が話す言語であるドメイン オブジェクトを取得する BLL のジョブが、それらを DAL が話す言語である DTO に変換し、その逆も同様であるということです。

さまざまなオブジェクトの作成が非常に簡単になりました。特に、必要に応じてジェネリック実装をオーバーライドし、単純な場合はそのままにしておくことができるためです。ここまでは順調ですね。

問題が発生したのは、プレゼンテーションで使用し始めたときだけです。参照として BLL ライブラリを含めましたがMyClassBLL,、 の定義を認識していないため、 のメソッドを使用できませんMyClassDto。これは、定義としてのメタデータにありMyClassBllます。

プレゼンテーション レイヤーが DAL クラスについて知る必要はありません。どうすればコンパイラを満足させることができますか? 現在の設計の柔軟性を維持しながら、プレゼンテーション層から DAL をさらに隠す方法はありますか?

参考までに、私の汎用 BLL クラスは次のようになります。

public abstract class Bll<TModel, TDto> : IBll<TModel, TDto>
    where TModel : class
    where TDto : class
{
    protected User User;

    protected static string[] AdminGroups;

    protected bool IsAdmin;

    protected static Func<UnitOfWork, GenericRepository<TDto>> Repository;

    private void AdminCheck()
    {
        if (!IsAdmin)
        {
            throw new SecurityException("That Action Requires Admin Privileges");
        }
    }

    public Bll(User user)
    {
        StaticMapBulder.initialize();
        if (User == null)
        {
            throw new ArgumentNullException("User Can not be null");
        }
        user = User;
        IsAdmin = false;
        foreach (var AdminGroup in AdminGroups)
        {
            if (user.IsInGroup(AdminGroup))
                {
                    IsAdmin = true;
                }
        }
    }

    public virtual TModel Insert(TModel ItemToAdd)
    {
        AdminCheck();
        using (var uow = new  UnitOfWork())
        {
            var OutgoingDto = MapModelToDto(ItemToAdd);
            var InboundDto = Repository(uow).Insert(OutgoingDto);
            uow.Save();
            return MapDtoToModel(InboundDto);

        }

    }

    public virtual List<TModel> GetAll()
    {
        using (var uow = new UnitOfWork())
        {
            var InboundDto = Repository(uow).Get();
            var ModelList = new List<TModel>();
            foreach (var item in InboundDto)
            {
                ModelList.Add(MapDtoToModel(item));
            }
            return ModelList;
        }

    }

    public virtual TModel GetByID(int ID)
    {
        using (var uow = new UnitOfWork())
        {
            var InboundDto = Repository(uow).GetByID(ID);
            return MapDtoToModel(InboundDto);
        }
    }

    public virtual void Update(TModel ItemToUpdate)
    {
        AdminCheck();
        using (var uow = new UnitOfWork())
        {
            var OutboundDto = MapModelToDto(ItemToUpdate);
            Repository(uow).Update(OutboundDto);
            uow.Save();
        }
    }

    public virtual void Delete(TModel ItemToDelete)
    {
        using (var uow = new UnitOfWork())
        {
            var OutboundDto = MapModelToDto(ItemToDelete);
            Repository(uow).Delete(OutboundDto);
            uow.Save();
        }
    }

    public virtual void DeleteByID(int ID)
    {
        using (var uow = new UnitOfWork())
        {
            Repository(uow).Delete(ID);
            uow.Save();
        }
    }


    virtual public TModel MapDtoToModel(TDto Dto)
    {
        return Mapper.Map<TModel>(Dto);
    }

    virtual public TDto MapModelToDto(TModel Model)
    {
        return Mapper.Map<TDto>(Model);
    }
}

}

そのクラスの一般的な実装は次のようになります。

public class MyClassBll : Bll<MyClass, MyClassDto>
{
    public MyClassBll(User user)
        : base(user)
    {

    }

    new protected static Func<UnitOfWork, GenericRepository<MyClassDto>> Repository = x => x.MyClassRepository;
    new protected static string[] AdminGroups = { "MyClassAdministrators" };
}
4

1 に答える 1