3

コントラクト (データ/サービスなど) がビジネス エンティティとは別のプロジェクトにあるソリューション構造があり、Automapper を使用して 3 番目のサービス実装プロジェクトからマッピングしています。

WCFProject.Service.BusinessLayer
WCFProject.Service.Contracts
WCFProject.Service.Impl

私の ServiceImpl はこれらの他のプロジェクトの両方を参照しており、ここで DataContract から BusinessEntity への自動マッピングが行われ、BusinessEntity オブジェクトで正しいメソッドが呼び出されます。

ここで、いくつか追加FaultContractsして、ビジネス ロジックでそれらを使用して、適切な例外をスローしたいと考えています。しかし、それらを Contracts プロジェクトに追加する場合 (すべての契約をまとめたいので理想的です)、BusinessLayer でそれらを使用するには、BusinessLayer から Contracts への参照が必要です。可能であればこれらを独立させ、これら 2 つのレイヤー間の DTO だけを扱いたいと考えていました。2 つのプロジェクトを独立させたいという私の側からの正当な同意はありますか? 例外もマップしますか? または、これに対処するより良い方法があります。

4

3 に答える 3

6

ビジネス層には、上記の層の知識が必要です。そのため、上に wcf レイヤーがあることについては何も知りません。エラーをスローすることは、wcf レイヤーからのものであり、そこで例外をキャッチして、何をしたいかを決定します。ビジネス例外は wcf 障害にマップできますが、nullpointer 例外の接続がある場合は、何かが間違っているという一般的な障害を与えるだけです。

サービス動作におけるハンドリング/マッピング エラーのサンプルは、ここにあります: WCF-Exception-Handling

于 2013-10-21T16:21:02.257 に答える
3

あなたが指定する質問で:

いくつかの FaultContract を追加し、それらをビジネス ロジックで使用して適切な例外をスローしたいと考えています。

ご指摘のとおり、これにより、サービスのパブリック API (サービス、データ、およびフォールト コントラクト) とビジネス ロジックが結合されます。理想的には、ビジネス ロジックは、サービスによって呼び出されているという事実にとらわれないようにする必要があります。そのため、コントラクト アセンブリへの参照は厄介です。

コントラクト アセンブリは、クライアントがサービスに関して公開している情報をレイアウトする必要があります。

namespace Contracts
{
    [ServiceContract]
    interface IMyService
    {
        [OperationContract]
        [FaultContract(typeof(MyFaultContract))]
        [FaultContract(typeof(AnotherFaultContract))]
        void MyOperation();
    }

    [DataContract]
    public class MyFaultContract
    {
        [DataMember]
        public string Problem { get; set; }
    }

    [DataContract]
    public class AnotherFaultContract
    {
        [DataMember]
        public string Description { get; set; }
    }
}

ソフトウェア開発における多くの問題と同様に、問題は間接的なレイヤーで対処できます。質問で指定したことにもかかわらず、ビジネスロジックをコントラクトアセンブリに結合したくありません。そうしないことの利点は明らかです。これにより、パブリック コントラクトと「内部」ビジネス ロジックが独立して進化できるようになります。

以下は、サービス実装を使用してコントラクトをビジネス ロジックに結合する例を示しています。ビジネス レイヤーの例外は、クライアントに返される障害コントラクトにマップされます。

namespace Service
{
    class MyService: IMyService
    {
        public void MyOperation()
        {
            try
            {
                var businessLogic = new BusinessLogic();
                businessLogic.DoOperation();
            }
            catch (KeyNotFoundException)
            {
                throw new FaultException<MyFaultContract>(new MyFaultContract
                {
                    Problem = "A key issue occurred in the service"
                });
            }
            catch (Exception)
            {
                throw new FaultException<AnotherFaultContract>(new AnotherFaultContract
                {
                    Description = "Something BAD happened in the service"
                });
            }
        }
    }
}

余談ですが、クライアントで公開する障害コントラクトと、サーバー側で問題が発生した場合にクライアントが必要とする情報について慎重に検討する価値があります。サービスの例外に関する情報を公開しすぎると、セキュリティ リスクになる可能性があります。

于 2013-10-22T11:25:20.140 に答える