5

ServiceServiceStack ライブラリの一部であるから派生したクラスに問題があります。またはメソッドから派生しServiceて配置する別のクラスをセットアップすると、すべてが正常に実行されますが、問題は、そのクラス自体がビジネスロジックへの参照を持たないことです。静的データを返す限りは問題ありませんが、それをビジネス ロジックに統合したい場合は機能しません。Get メソッドを、ビジネス ロジックと同じクラスの一部にしたいと考えています。それは悪い設計ですか?それを回避するにはどうすればよいですか? 私が得ているエラーは、派生元のクラスが何らかの理由でインスタンス化されるということです(私の現在の理解によれば、これは私にはほとんど意味がありません)。から派生したクラスである必要がありますGetAnyServiceService、ルーティングロジックを整理するだけではありませんか?

ここに私の問題を説明するためのいくつかのコードがあります:

このコードは正常に実行されますが、問題はクラスがクラスDTOの内容について何も知らないことですClassWithBusinessLogic:

public class ClassWithBusinessLogic
{
    public ClassWithBusinessLogic()
    {
        string hostAddress = "http://localhost:1337/";

        WebServiceHost host = new WebServiceHost("MattHost", new List<Assembly>() { typeof(DTOs).Assembly });
        host.StartWebService(hostAddress);
        Console.WriteLine("Host started listening....");

        Console.ReadKey();
    }
}

public class HelloWorldRequest : IReturn<string>
{
    public string FirstWord { get; set; }

    public HelloWorldRequest(string firstWord)
    {
        FirstWord = firstWord;
    }
}

public class DTO : Service
{
    public string Get(HelloWorldRequest request)
    {
        return request.FirstWord + " World!!!";
    }
}

さて、実際に私が欲しいのは次のとおりですが、コードは予期しない動作をします。基本的には機能していません。

public class ClassWithBusinessLogic : Service
{
    private string SomeBusinessLogic { get; set; }

    public ClassWithBusinessLogic()
    {
        string hostAddress = "http://localhost:1337/";

        //Simplistic business logic
        SomeBusinessLogic = "Hello";

        WebServiceHost host = new WebServiceHost("MyHost", new List<Assembly>() { typeof(DTO).Assembly });
        host.StartWebService(hostAddress);
        Console.WriteLine("Host started listening....");

        Console.ReadKey();
    }

    public string Get(HelloWorldRequest request)
    {
        return SomeBusinessLogic;
    }
}

public class HelloWorldRequest : IReturn<string>
{
    public string FirstWord { get; set; }

    public HelloWorldRequest(string firstWord)
    {
        FirstWord = firstWord;
    }
}

実行するには、次のクラスも必要です。

public class WebServiceHost : AppHostHttpListenerBase
{
    public WebServiceHost(string hostName, List<Assembly> assembliesWithServices) : base(hostName, assembliesWithServices.ToArray())
    {
        base.Init();
    }

    public override void Configure(Funq.Container container)
    { }

    public void StartWebService(string hostAddress)
    {
        base.Start(hostAddress);
    }

    public void StopWebService()
    {
        base.Stop();
    }
}

public class WebServiceClient
{
    private JsonServiceClient Client { get; set; }

    public WebServiceClient(string hostAddress)
    {
        Client = new JsonServiceClient(hostAddress);
    }

    public ResponseType Get<ResponseType>(dynamic request)
    {
        return Client.Get<ResponseType>(request);
    }

    public void GetAsync<ResponseType>(dynamic request, Action<ResponseType> callback, Action<ResponseType, Exception> onError)
    {
        Client.GetAsync<ResponseType>(request, callback, onError);
    }
}

class Client_Entry
{
    static void Main(string[] args)
    {
        Client client = new Client();
    }
}

public class Client
{

    public Client()
    {
        Console.WriteLine("This is the web client. Press key to start requests");
        Console.ReadKey();

        string hostAddress = "http://localhost:1337/";
        WebServiceClient client = new WebServiceClient(hostAddress);

        var result = client.Get<string>(new HelloWorldRequest("Hello"));
        Console.WriteLine("Result: " + result);

        Console.WriteLine("Finished all requests. Press key to quit");
        Console.ReadKey();
    }

    private void OnResponse(HelloWorldRequest response)
    {
        Console.WriteLine(response.FirstWord);
    }

    private void OnError(HelloWorldRequest response, Exception exception)
    {
        Console.WriteLine("Error. Exception Message : " + exception.Message);
    }

}
4

1 に答える 1

3

2 番目のコード ブロックの読み取り方法は、Service Host と Service が同じオブジェクトであることを示しています。私が見るところ

public ClassWithBusinessLogic()
{
    string hostAddress = "http://localhost:1337/";

    //Simplistic business logic
    SomeBusinessLogic = "Hello";

    WebServiceHost host = new WebServiceHost("MyHost", new List<Assembly>() { typeof(DTO).Assembly });
    host.StartWebService(hostAddress);
    Console.WriteLine("Host started listening....");

    Console.ReadKey();
}

次に、そのコンストラクターは ServiceStack WebServiceHost をインスタンス化し、独自のアセンブリを渡します。これにより、ServiceStack は Service から継承されるため、ClassWithBusinessLogic() を再初期化し、無限ループに陥る可能性があると思われます。

懸念事項を分離する必要があります。Web サービス ホスト、Web サービス、およびビジネス ロジック クラスはすべて分離されています。あなたがやっている方法でそれらを混ぜ合わせることは、あなたを欲求不満に導くだけです. それらを独自のクラスに分けます。ビジネス ロジックは、IoC コンテナーを介して Web サービスに渡すことができます。

したがって、次のような結果になります。

class BusinessLogicEngine : IBusinessLogic
---> Define your business logic interface and implementation, and all required business object entities

class WebService : Service
   constructor(IBusinessLogic)
---> Purely handles mapping incoming requests and outgoing responses to/from your business object entities. Recommend using AutoMapper (http://automapper.org/) 
---> Should also handle returning error codes to the client so as not to expose sensitive info (strack traces, IPs, etc)


class WebServiceHost
---> Constructor initializes the WebServiceHost with the typeof(WebService) from above.
于 2013-05-28T16:01:01.317 に答える