2013-05-28 14 views
5

Mam problem z klasą, która pochodzi z Service, która jest częścią biblioteki ServiceStack. Jeśli ustawię oddzielną klasę, która wywodzi się z Service i umieszczę w niej metody Get lub Any, wszystko działa dobrze, jednak problem polega na tym, że sama ta klasa nie ma odniesienia do żadnej z logiki biznesowej. Jest w porządku, dopóki zwracam statyczne dane, ale jeśli chcę zintegrować je z logiką biznesową, to nie działa. Chcę, aby metoda Get była częścią tej samej klasy, w której leży moja logika biznesowa. Czy to zły projekt i czy mogę go obejść? Błąd, który dostaję, polega na tym, że klasa wywodząca się z Service zostaje utworzona z dowolnego powodu (co zgodnie z moim obecnym zrozumieniem ma dla mnie bardzo mały sens). Czy klasa, wywodząca się z Service, nie tylko uporządkuje logikę routingu?ServiceStack, gdzie umieścić logikę biznesową?

Oto niektóre kod do zilustrowania mój problem:

Ten kod działa poprawnie, ale problemem jest to, że klasa DTO nic nie wie o treści klasie 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!!!"; 
    } 
} 

Teraz, po to rzeczywiście to, co Chcę, ale kod zachowuje się nieoczekiwanie, w zasadzie nie działa:

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; 
    } 
} 

Aby uruchomić poniższy kod Potrzebne są również osły:

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); 
    } 

} 
+0

należy oddzielić kod nieco więcej, klasa, która wywodzi się od służby powinny nadal do czynienia tylko z kwestiami usług internetowych, czyli - Otoczenie kodów błędów, a nie logika biznesowa, IMO. – Mithir

+0

Rzetelne punkty, ale nie odpowiada na pytanie, w jaki sposób zwracam np. Ciąg "SomeBusinessLogic" w ClassWithBusinessLogic. –

Odpowiedz

3

Sposób, w jaki odczytuje drugi blok kodu, pokazuje, że host usługi i usługa to ten sam obiekt. Gdzie widzę

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(); 
} 

To konstruktor następnie instancję ServiceStack WebServiceHost, przechodząc w swoim zespole - to prowadzi mnie do przypuszczenia, że ​​ServiceStack będzie ponownie zainicjować ClassWithBusinessLogic() ponieważ dziedziczy on z Serwisu, potencjalnie going down nieskończona pętla.

Musisz oddzielić swoje obawy - Twój Host Web Service, Twoja usługa internetowa i klasa Business Logic są oddzielne. Wymieszanie ich w taki sposób, w jaki postępujesz, doprowadzi cię tylko do frustracji. Oddziel je na własne klasy. Logika biznesowa może zostać przekazana do serwisu internetowego za pośrednictwem kontenera IoC.

Więc chcesz skończyć z czymś takim:

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. 
Powiązane problemy