ServiceStack,业务逻辑应该放在哪里?

5
我遇到了一个与ServiceStack库中派生自Service类的类有关的问题。如果我设置一个单独的类,该类派生自Service并且使用Get或Any方法,则一切都运行良好。但是问题在于,该类本身没有引用任何业务逻辑。只要我返回静态数据,就没问题,但是如果我想将其集成到业务逻辑中,则无法工作。我希望Get方法是同一类中的一部分,其中包含我的业务逻辑。这是否是糟糕的设计?如果是,我该怎么办才能解决它?我得到的错误是,由Service派生的类以某种原因实例化(根据我的目前理解,这毫无意义)。从Service派生的类不应该只处理路由逻辑吗?
以下是一些代码来说明我的问题:
这段代码运行良好,但问题在于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);
    }

}

你应该更加分离你的代码,一个继承自 Service 的类应该仅处理 Web 服务问题,例如设置错误代码,而不是业务逻辑。我个人认为。 - Mithir
有道理,但这并没有回答我如何在ClassWithBusinessLogic中返回例如字符串'SomeBusinessLogic'的问题。 - Matt
1个回答

3
您的第二个代码块表明您的服务主机和服务是同一个对象。我看到的是:
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,并传入自己的程序集 - 这使我相信,由于ClassWithBusinessLogic()从Service继承,ServiceStack将重新初始化它,可能会导致无限循环。

您需要分离出不同的职责 - 您的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.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接