ServiceStack nowa usługa obok siebie ASP.NET strona MVC

W przykładach dla ServiceStack nie widzę ani jednej aplikacji, która jest ASP.NET najpierw strona MVC, a następnie serwis ServiceStack.

Weźmy bardzo prosty ASP.NET aplikacja webowa MVC, która renderuje produkty poprzez widoki. Wykorzystuje Kontrolery, widoki, modele i viewmodele.

Załóżmy, że mamy model Product, który zostaje zapisany w DB dokumentu. Załóżmy, że mamy viewmodel ProductViewModel, który jest mapowany z Product i wyświetlany wewnątrz MVC Razor View/PartialView.

Więc to jest strona internetowa rzeczy..Załóżmy teraz, że chcemy dodać usługę zwracającą produkty do różnych klientów, takich jak Aplikacje Windows 8.

Czy klasy request/response powinny być całkowicie odłączone od tego, co już mamy? Nasz ProductViewModel może zawierać już wszystko, co chcemy zwrócić z serwisu.

Ponieważ mamy już Product (klasa modelu), nie możemy mieć innej Product klasy w przestrzeni nazw API..moglibyśmy, ale to sprawia, że sprawy są niejasne i chciałbym tego uniknąć.

Czy zatem powinniśmy wprowadzić samodzielną klasę ProductRequest oraz klasę ProductRequestResponse (inherits ProductViewModel) w przestrzeni nazw API?

Tak jak ProductRequestResponse : ProductViewModel?

Chodzi mi o to, że mamy już klasy Model i ViewModel i aby skonstruować klasy Request I Response dla usługi SS musielibyśmy utworzyć kolejne dwa pliki, głównie kopiując wszystko z klas, które już mamy. Nie wygląda mi to na sucho, może postępuj zgodnie z wytycznymi dotyczącymi rozdzielania problemów, ale suchość jest również ważna, w rzeczywistości bardziej niż oddzielanie wszystkiego (oddzielanie wszystkiego prowadzi do powielania kodu).

Chciałbym zobaczyć przypadek, w którym aplikacja webowa została już stworzona, obecnie zawiera modele i Viewmodele i zwraca odpowiednie widoki do wyświetlania w Internecie, ale może być rozszerzona na w pełni funkcjonalną usługę obsługującą klientów programmatic? Jak klienci AJAX itp...z tym, co już mam.

Inna sprawa:

Jeśli spojrzeć na ten przykład https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.MovieRest/MovieService.cs

Zobaczysz tam Movie Request class i Movies Request class (jedna dla pojedynczego żądania filmu, druga dla listy filmów). W związku z tym istnieją również dwie usługi, MovieService i MoviesService, jedna zajmująca się wnioskami o jeden film, druga o gatunek filmu.

Teraz, podczas gdy Lubię podejście SS do usług i myślę, że jest to właściwe, nie lubię tego rodzaju separacji tylko ze względu na rodzaj żądania. A gdybym chciał filmy według reżysera? Czy będę wymyślał jeszcze jedną klasę request posiadającą Director właściwość i jeszcze inną usługę (MoviesByDirector) dla niej?

Myślę, że próbki powinny być zorientowane na jedną usługę. Wszystko, co ma do czynienia z filmami, musi znajdować się pod jednym dachem. Jak można to osiągnąć z ServiceStack?

public class ProductsService : Service
{
    private readonly IDocumentSession _session;
    private readonly ProductsHelperService _productsHelperService;
    private readonly ProductCategorizationHelperService _productCategorization;

    public class ProductRequest : IReturn<ProductRequestResponse>
    {
        public int Id { get; set; }
    }

    // Does this make sense? 
    // Please note, we use ProductViewModel in our Views and it holds everything we'd want in service response also
    public class ProductRequestResponse : ProductViewModel
    {
    }

    public ProductRequestResponse GetProducts(ProductRequest request)
    {
        ProductRequestResponse response = null;
        if (request.Id >= 0)
        {
            var product = _session.Load<Product>(request.Id);
            response.InjectFrom(product);
        }
        return response;
    }
}
Author: mare, 2013-03-12

2 answers

Warstwa usług jest Twoim najważniejszym kontraktem

Najważniejszym interfejsem, jaki możesz kiedykolwiek stworzyć w całym systemie jest twoja zewnętrzna umowa serwisowa, to jest to, co konsumenci Twojej usługi lub aplikacji będą wiązać, tj. istniejące witryny połączeń, które często nie zostaną zaktualizowane wraz z bazą kodu-każdy inny model jest drugorzędny .

Dto to najlepsze praktyki dla usług zdalnych.]}

W następstwie zalecenia Martina Fowlera dla korzystanie z DTOs (Obiekty transmisji danych) dla usług zdalnych (MSDN), ServiceStack dll. Dzięki temu możesz ponownie korzystać z typowanych DTOs używanych do definiowania usług w stanie, w jakim są, w klientach C#/. Net - zapewniając kompleksowe typowane API bez użycia kodu gen lub innych sztucznych narzędzi maszyny.

DRY vs Intent

Utrzymywanie rzeczy w stanie suchym nie powinno być mylone z wyraźnym stwierdzeniem intencji, których należy unikać prób osuszania lubukrywania się za dziedziczeniem , magicznymi właściwościami lub jakimkolwiek innym mechanizmem. Przejrzyste, dobrze zdefiniowane Dto stanowi jedno źródło odniesienia, na które każdy może spojrzeć, aby zobaczyć, co każda usługa akceptuje i zwraca, pozwala programistom klientów i serwerów natychmiast rozpocząć pracę i powiązać się z zewnętrznymi modelami usług bez napisania implementacji.

Oddzielenie DTOs daje również swobodę ponownego uwzględniania implementacji od wewnątrz bez rozbijania zewnętrznych klientów, tzn. Twoja usługa zaczyna buforować odpowiedzi lub wykorzystuje rozwiązanie NoSQL do wypełniania odpowiedzi.

Zapewnia również autorytatywne źródło (które nie jest wyciekło lub połączone wewnątrz logiki aplikacji), które jest używane do tworzenia automatycznie generowanych stron metadanych, przykładowych odpowiedzi, Swaggera wsparcie, XSDs, WSDLs itp.

Korzystanie z wbudowanego automatycznego mapowania ServiceStack

Chociaż zachęcamy do utrzymywania oddzielnych modeli DTO, nie musisz utrzymywać własnego ręcznego mapowania, ponieważ możesz użyć mapera, takiego jak AutoMapper lub korzystając z wbudowanej obsługi automatycznego mapowania ServiceStack, np:

Utwórz nową instancję DTO, wypełnioną pasującymi właściwościami na viewModel:

var dto = viewModel.ConvertTo<MyDto>();

Zainicjalizuj DTO i uzupełnij go pasującymi właściwościami w widoku model:

var dto = new MyDto { A = 1, B = 2 }.PopulateWith(viewModel);

Zainicjalizuj DTO i uzupełnij go o nie-domyślne pasujące właściwości w modelu widoku:

var dto = new MyDto { A = 1, B = 2 }.PopulateWithNonDefaultValues(viewModel);

Zainicjalizuj DTO i uzupełnij go pasującymi właściwościami, które są przypisane atrybutem Attr w modelu widoku:

var dto = new MyDto { A=1 }.PopulateFromPropertiesWithAttribute<Attr>(viewModel);

Gdy logika mapowania staje się bardziej skomplikowana, lubimy używać metod rozszerzeń, aby utrzymać suchy kod i utrzymać mapowanie w jednym miejscu, które jest łatwo zużywalne z poziomu aplikacji, e. g:

public static class MappingExtensions
{
    public static MyDto ToDto(this MyViewModel viewModel)
    {
        var dto = viewModel.ConvertTo<MyDto>();
        dto.Items = viewModel.Items.ConvertAll(x => x.ToDto());
        dto.CalculatedProperty = Calculate(viewModel.Seed);
        return dto;
    }
}

Który jest teraz łatwo zużywalny za pomocą tylko:

var dto = viewModel.ToDto();
 70
Author: mythz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-27 13:45:56

Jeśli nie jesteś przywiązany specjalnie do ServiceStack i po prostu chcesz " w pełni funkcjonalny serwis do obsługi klientów programmatic ... z tym, co już mamy", Możesz spróbować wykonać następujące czynności: niech twoje Kontrolery zwrócą ViewResult LUB JsonResult na podstawie nagłówka accept żądania - Request.AcceptTypes.Contains("text/html") lub Request.AcceptTypes.Contains("application/json").

Zarówno ViewResult, jak i JsonResultActionResult, więc sygnatura działań pozostaje taka sama, a zarówno View(), jak i Json() akceptują model widoku. Ponadto, jeśli masz bazę kontrolną, możesz zrobić metoda bazowa (na przykład protected ActionResult RespondWith(Object viewModel)), która wywołuje View() lub Json (), więc zmiana istniejącego kodu jest minimalna.

Oczywiście, jeśli Twoje Viewmodelki nie są czyste (tzn. mają coś specyficznego dla html lub polegasz na magii ViewBag), to jest to trochę więcej pracy. Nie otrzymasz SOAP ani innych typów wiązań dostarczanych przez ServiceStack, ale jeśli twoim celem jest obsługa interfejsu danych JSON z minimalnymi zmianami kodu w istniejącej aplikacji MVC, może to być rozwiązanie.

Lp

 2
Author: Boris B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-10 22:36:50