3

WCF を介してサービスを提供しています。SQL Server のデータは、Entity Framework、Automapper、および DTO を使用して公開されています。

DTO で属性を提供することに問題はありませんが、クラス ライブラリに保持したい他のメソッドを実装する方法がわかりません。

サービス全体のすべてのメソッドを 1 つの WCF サービス実装に入れるのではなく、クラス ライブラリに実装されているメソッドを参照するだけです。

クラス ライブラリを介してビジネス ロジック層を実装し、WCF を介してプレゼンテーション層に公開し、DTO を使用してデータを渡すにはどうすればよいでしょうか。

公開されたクラス メソッドは、どのように DTO を参照していますか? クラス ライブラリはレイヤーごとに分割する必要がありますか?

サービス要素

【サービス契約】

public interface Interface1
{
    [OperationContract]
    Class1 GetClass1(int id);

    [OperationContract]
    Class2 GetClass2(int id);
}

クラス ライブラリ要素

public class Class1 : Interface1
{
    public Class1 GetClass1(int id) { 
        // implementation

    }
}

public class Class2 : Interface1
{
    public Class2 GetClass2(int id)
    {
        // implementation

    }

}

DTO

[DataContract]
public class Class1
{
    [DataMember]
    public int x { get; set;}
}

[DataContract]
public class Class2
{
    [DataMember]
    public int y { get; set;}
}
4

3 に答える 3

1

あなたの質問を正しく理解できれば。自動的に公開されるすべてのメソッドは必要ありません。いくつかのメソッドのみを抽象化する場合は、サービスとクラス サービスの両方で共通の DTO を共有する必要があります。

于 2013-09-20T16:02:47.830 に答える
1

最初に、あなたが何をしようとしているのか(私は思う)を明確にさせてください:

WCF を介して公開したいビジネス ロジックがあり、最終的にはプレゼンテーション レイヤーで使用されます。ビジネス ロジックには、データベースへのアクセスと、ORM および AutoMapper の使用が含まれていました。あなたの質問の目的のために、この実装の詳細は無関係だと思います。

それがどのように見えるかの最初の反復を行いましょう (異なる名前空間を異なるアセンブリに分離します)。

namespace Contracts
{
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        Data GetData(int id);
    }

    [DataContract]
    public class Data
    {
        [DataMember]
        public string PropertyValue { get; set; }
    }
}

namespace ClassLibrary
{

    public class BusinessLogicImplementation: IMyService
    {
        public Data GetData(int id)
        {
            /**
             * Do data retrieval here, which returns returnedData
             * */
            DataModel returnedData;
            return Mapper.Map<DataModel, Data>(returnedData);
        }
    }
}

namespace EntityFrameworkModel
{

    public class DataModel
    {
        public string PropertyValue { get; set; }
    }
}

Contracts アセンブリには、サービスとクライアントの両方に公開されるデータが含まれています。これは、クライアントがアセンブリへのバイナリ参照によって、またはコントラクトの独自のローカル実装 (Visual Studio サービス参照など) を持つクライアントによって使用できます。

クラス ライブラリ アセンブリには、データ取得とビジネス ロジックの実装が含まれています。データモデルも示しましたが、追加のコンテキストのみです-これはあなたの質問には関係ないと思います:

これまでのところ、あなたの質問の一部に答えました:

「クラス ライブラリを介してビジネス ロジック層を実装し、WCF を介してプレゼンテーション層に公開し、DTO を使用してデータを渡すにはどうすればよいでしょうか?」

次に、クエリの最初の部分を考えてみましょう。

「サービス全体のすべてのメソッドを単一の WCF サービス実装に入れるのではなく、クラス ライブラリに実装されているメソッドを参照したいだけです。」

明示的に提案していませんが、これは、WCF サービスがクライアントに関連するよりも多くのメソッドを公開していることを示唆しています。クライアントが見ているインターフェイスを簡潔にし、クライアントが達成したいことに関連したものにしたいのは当然です。

これは、さまざまなインターフェイスで表されるサービスのさまざまなエンドポイントを公開することで実現されます。コードに関しては、ビジネス ロジックの実装と WCF を介して公開される実装の間にレイヤーを追加します。

namespace Contracts
{
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        Data GetData(int id);
    }

    [DataContract]
    public class Data
    {
        [DataMember]
        public string PropertyValue { get; set; }
    }
}

namespace MoreContracts
{
    [ServiceContract]
    public interface IOtherService
    {
        [OperationContract]
        MoreData GetMoreData(int id);
    }

    [DataContract]
    public class MoreData
    {
        [DataMember]
        public string MorePropertyValue { get; set; }
    }
}

namespace Service
{
    /**
     * This class adds an extra layer between the exposed functionality and the implementation.
     * It effectively is used for hosting all the business logic you want to expose over the service,
     * including that contained in ClassLibrary and anywhere else.
     * */
    public class ServiceImplementation: IMyService, IOtherService
    {

        public Data GetData(int id)
        {
            return new BusinessLogicImplementation().GetData(id);
        }

        public MoreData GetMoreData(int id)
        {
            //Implementation of logic not in class library
        }
    }
}

namespace ClassLibrary
{
    public class BusinessLogicImplementation : IMyService
    {
        public Data GetData(int id)
        {
            /**
             * Do data retrieval here, which returns returnedData
             * */
            DataModel returnedData;
            return Mapper.Map<DataModel, Data>(returnedData);
        }
    }
}

オンラインで簡単に検索すると、ホスティング シナリオで複数のエンドイントを使用してサービスをホストするために何をする必要があるかがわかります。たとえば、セルフ ホスティングについては、Run WCF ServiceHost with multiple contractを参照してください。

于 2013-09-25T11:18:07.160 に答える