2013-05-28 12 views
5

Ho un problema con la classe che deriva da Service, che fa parte della libreria di ServiceStack. Se si imposta una classe separata che deriva da Service e si posizionano i metodi Get o Any all'interno, allora tutto funziona correttamente, tuttavia, il problema è che la classe stessa non ha riferimenti a nessuna delle logiche di business. Va bene finché restituisco i dati statici, ma se voglio integrarlo nella logica aziendale, allora non funziona. Voglio che il metodo Get faccia parte della stessa classe in cui si trova la mia logica aziendale. È un cattivo design e se cosa posso fare per aggirarlo? L'errore che sto ottenendo è che la classe che deriva da Service viene istanziata per qualsiasi motivo (che secondo la mia attuale comprensione ha poco senso per me). La classe, derivante da Service, non deve solo risolvere la logica di routing?ServiceStack, dove posizionare la logica aziendale?

Qui po 'di codice per illustrare il mio problema:

Questo codice viene eseguito bene, ma il problema è che la classe DTO sa nulla sul contenuto della classe 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!!!"; 
    } 
} 

Ora, il seguente è in realtà ciò che Voglio ma il codice si comporta inaspettatamente, in sostanza non funziona:

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

Per eseguire il seguente cl asini sono necessari così:

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

si dovrebbe separare il codice di un po 'di più, una classe che deriva dal servizio dovrebbe comunque trattare solo con i problemi di servizio web, vale a dire - l'impostazione codici di errore, e non logica aziendale, IMO. – Mithir

+0

Punti giusti, ma non risponde alla domanda come restituire ad esempio la stringa "SomeBusinessLogic" all'interno di ClassWithBusinessLogic. –

risposta

3

Il modo in cui il secondo blocco di codice legge dimostra che il vostro Host servizio e il vostro servizio sono lo stesso oggetto. Dove vedo

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

Questo costruttore quindi un'istanza della ServiceStack WebServiceHost, passando nella sua propria assemblea - questo mi porta a credere che ServiceStack sarà poi ri-inizializzare ClassWithBusinessLogic() in quanto eredita da servizio, potenzialmente scendendo un infinito ciclo continuo.

È necessario separare i propri dubbi: l'host del servizio Web, il servizio Web e la classe di business logic sono tutti separati. Il fatto di mescolarli al modo in cui stai facendo ti porterà solo alla frustrazione. Separali nelle loro classi. La tua logica aziendale può essere trasferita nel tuo servizio web tramite il contenitore IoC.

modo che ci si finisce con qualcosa di simile:

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. 
Problemi correlati